TypeScript는 기본적으로 변수 뒤에 콜론(:)과 타입 이름을 명시하는 타입 주석(type annotaion)을 함께 기재한다.
let n : number = 1; //type annotation
let m = 2; //type inference (변수 m의 타입은 number로 추론된다.)
😲❓ TypeScript라고해서 모든 변수에 일일이 타입을 지정해야 하는 것은 아니다. 타입 부분을 생략할 수 있다.
변수의 타입 부분이 생략되면 대입 연산자의 오른쪽 값을 분석해 변수의 타입을 결정한다. 이를 타입 추론이라고 한다.
자바스크립트 소스코드와 호환성을 보장하는데 큰 역할을 한다. js 파일을 확장자만 ts로 바꾸면 타입스크립트 환경에서도 바로 동작한다.
형식적인 코드 작성을 줄일 수 있다.
const oneOrThree: 1 | 3 = 3;
// const oneOrThree = 3;
// 3을 할당하는 것만으로는 1 | 3을 추론할 수 없다.
대부분의 경우 타입 추론은 직관적이지만 개발자가 의도치 않은 방향으로의 추론을 방지하기 위해 타입 추론 방식을 알아보자.
let x = 3; // number 타입으로 추론
const y = 3; // 3 타입으로 추론
let x = [0, 1, null] // x의 타입 number | null
interface Animal {
legs: number;
}
interface Dog extends Animal {
bark(): void;
}
interface Cat extends Animal {
meow(): void;
}
let dog: Dog;
let cat: Cat;
const dogAndCat = [dog, cat];
// dogAndCat의 타입은 Animal[]이 아닌 Array<Dog | Cat>으로 추론된다.
상위 타입인 Animal[]
로 자동 추론하는 경우 아래 상황에서 오류가 발생한다.
interface Animal {
legs: number;
}
interface Dog extends Animal {
bark(): void;
}
interface Cat extends Animal {
meow(): void;
}
interface Camel extends Animal {
humps: number;
}
let dog: Dog;
let cat: Cat;
const dogAndCat = [dog, cat];
function getSoundFunction(dogOrCat: Animal[]) {
if ('meow' in dogOrCat) {
return dogOrCat.meow;
} else {
return dogOrCat.bark;
}
}
dogAndCat.map(dogOrCat => getSoundFunction(dogOrCat));
dogAndCat
배열에는 Camel 타입의 변수가 존재하지 않음에도 위의 코드에서는 타입 에러가 발생한다. 이런 불편함을 막고자 최적 공통 타입에서의 타입 추론은 사용된 값들의 타입만을 재료로 사용한다.
타입 추론은 할당 받는 값(왼쪽 항)의 타입 뿐 아니라
할당"하는" 값인 오른쪽 항에 대해서도 타입을 추론한다. 이렇게 추론된 타입을 contextual type이라 부른다. 문맥상 위치에 의해 타입이 암시될 때 발생한다.
window.onmousedown = function(mouseEvent) {
console.log(mouseEvent.button); // 성공 (button 프로퍼티 존재)
console.log(mouseEvent.a); // 오류 (a 프로퍼티는 없음을 추론 가능)
};
window.onmousedown
이 (event: MouseEvent) => void
라 추론한다.mouseEvent.button
과 mouseEvent.a
에 대한 타입 추론도 이루어진다. 만약 타입 표기가 주어진다면 문맥상 타입은 무시된다.
window.onmousedown = function(mouseEvent: any) {
console.log(mouseEvent.a); // 오류 발생하지 않음.
};
참고자료
https://ahnheejong.gitbook.io/ts-for-jsdev/06-type-system-deepdive/type-assertion
https://typescript-kr.github.io/pages/type-inference.html