function range(start: number, limit: number) {
const out = []; // type: any[]
for (let i = start; i < limit; i++) out.push(i); // type: any[]
return out; // type: number[]
}
out의 타입은 any[]로 선언되었지만 number 타입의 값을 넣는 순간부터 타입은 number[]로 진화한다. any 타입의 진화는 noImplicitAny가 설정된 상태에서 변수의 타입이 암시적으로 any인 경우에만 일어난다.
let val: any; // type: any
if (Math.random() < 0.5) {
val = /hello/;
return val; // type: any
} else {
val = 12;
return val; // type: any
}
하지만 명시적으로 any를 선언하면 타입이 그대로 유지된다.
function range(start: number, limit: number) {
const out = [];
if (start === limit) return out; // ❌ 'out'변수에는 암시적으로 'any[]'형식이 포함됩니다.
for (let i = start; i < limit; i++) out.push(i);
return out;
}
any 타입의 진화는 암시적 any타입에 어떤 값을 할당할 때만 발생한다. 그리고 어떤 변수가 암시적 any 상태일 때 값을 읽으려고 하면 오류가 발생한다.
function range(start: number, limit: number) {
const out = [];
range(start, limit).forEach((i) => out.push(i * i));
return out; // ❌ 'out'변수에는 암시적으로 'any[]' 형식이 포함됩니다.
}
❗ 암시적 any 타입은 함수 호출을 거쳐도 진화하지 않는다.
✔️ any 특징
❗ unknown 타입인 채로 값을 사용하면 오류가 발생한다.
변수 선언을 할 때 어떠한 값이 있지만 그 타입을 모르는 경우에 unknown을 사용한다.
ex) parseYAML
✔️ unknown에서 원하는 타입으로 변경
function processValue(val: unknown) {
if (val instanceof Date) val; // type: Date
}
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: Book
}
✔️ object, {} vs unknown
타입 체커는 Document와 HTMLElement의 내장 속성에 대해서는 알고 있지만, 임의로 추가한 속성에 대해서는 알지 못한다.
document.monkey = "Tamarin"; // ❌ 'Document' 유형에 'monkey' 속성이 없습니다.
(document as any).monkey = "Tamarin"; // 정상
✔️ 최선의 해결책 : document 또는 DOM으로부터 데이터를 분리하는 것
분리할 수 없는 경우
interface Document {
monkey: string;
}
document.monkey = "Tamarin";
👍 any보다 나은 점
타입이 더 안전함. 타입 체커는 오타나 잘못된 타칩의 할당을 오류로 표시
속성에 주석을 붙일 수 있음
속성에 자동완성을 사용할 수 있음
더 구체적인 타입 단언문 사용하기
interface MonkeyDocument extends Document {
monkey: string;
}
(document as MonkeyDocument).monkey = "Macaque";
❗noImplicitAny가 설정되어 있어도, 명시적 any 또는 서드파티 타입 선언(@types)을 통해 any 타입은 코드 내에 여전히 존재할 수 있다.
npm의 type-coverage 패키지 활용하여 any추적
$ npx type-coverage
$ npx type-coverage --detail