any를 쓰면 안되는 이유 → 깔끔, 정확, 명료한 코드 작성을 위해 제대로 된 타입 설계는 필수인데 이 타입 설계가 명확해지지 않아 코드를 읽기 힘들어짐.
편집기에서 rename symbol로 타입의 이름을 변경할 수 있다!?
그럼에도 불구하고 any는 점진적 마이그레이션을 위해 존재해야 함.
더 잘 쓰는 방법
interface Foo { foo: string; }
interface Bar { bar: string; }
declare function expressionReturningFoo(): Foo;
function processBar(b: Bar) { /* ... */ }
function f1() {
const x: any = expressionReturningFoo(); // Don't do this
processBar(x);
}
function f2() {
const x = expressionReturningFoo();
processBar(x as any); // Prefer this
}
const config1: Config {
a: 1,
b: 2,
c: {
key: value // 에러, Foo 타입에 foo 프로퍼티가 필요하지만 Bar 타입에는 없습니다.
}
}
const config2: Config {
a: 1,
b: 2,
c: {
key: value
} as any // 정상, a,b 프로퍼티 마저 타입체크 안됨
}
const config3: Config {
a: 1,
b: 2,
c: {
key: value as any // 정상, a,b 프로퍼티 마저 타입체크 가능
}
}
function getLengthBad(array: any) {
return array.length;
}
// better than above.
function getLength(array: any[]) {
return array.length;
}
// 배열의 배열 형태 : any[][]
// value만 모를 때
function paramTest({[key: string]: any}) {
...
}
// ㅊㄱ) object 타입은 속성에 접근할 수 없음.
// 함수의 any
type Function0 = () => any; // 매개변수 0개만 가능
type Function1 = (arg: any) => any; // 매개변수 1개만 가능
type Function2 = (...args: any[]) => any; // 매개변수 몇 개든 가능.
function shallowObjectEqual<T extends object>(a: T, b: T): boolean {
for (const [k, aVal] of Object.entries(a)) {
if (!(k in b) || aVal !== (b as any)[k]) {
return false;
}
}
return Object.keys(a).length === Object.keys(b).length;
}
function range(start: number, limit: number) {
const out = [];
for (let i = start; i < limit; i++) {
out.push(i);
}
return out; // Return type inferred as number[]
}
function makeSquares(start: number, limit: number) {
const out = [];
// ~~~ Variable 'out' implicitly has type 'any[]' in some locations
range(start, limit).forEach(i => {
out.push(i * i);
});
return out;
// ~~~ Variable 'out' implicitly has an 'any[]' type
}
function processValue(val: unknown) {
if (val instanceof Date) {
val // Type is Date
}
}
//or
function isBook(val: unknown): val is Book {
return (
typeof(val) === 'object' && val !== null &&
'name' in val && 'author' in val
);
}
function processValue(val: unknown) {
if (isBook(val)) {
val; // Type is Book
}
}