TypeScript
는 타입이 정의되어있지 않은 변수의 타입을 자동으로 추론해주는 기능이 있다. 😀
이러한 기능으로 모든 변수에 일일이 타입을 정의하지 않아도 돼서 간결한 코드를 만들 수 있다.
어떠한 상황에서 타입 추론이 가능하며, 어떤 원리로 추론을 하는 지에 대해 알아보자❗️
변수의 초기값
을 기준으로 타입을 추론한다.
let a = 10; // number 타입으로 추론
let b = "hello"; // string 타입으로 추론
let c = { // id, name, profile, urls 프로퍼티가 있는 객체 타입으로 추론
id: 1,
name: "jaehan",
profile: {
nickname: "winterlood",
},
urls: ["https://velog.io/@jae_han_e/posts"],
};
let { id, name, profile } = c;
// id: number, namme: string, profile: {nickname: string}
let [one, two, three] = [1, "hello", true];
// one: number, two: string, three: boolean
함수의 return 값
을 기준으로 타입을 추론한다.
param 의 경우 default 값
으로 param의 타입을 추론한다.
function func() { // 반환값이 string 타입으로 추론된다
return "hello";
}
function func(message = "hello") { // message: string
return "hello";
}
선언한 값이 타입과 맞지 않더라도 as Type
을 통해 타입을 단언해 에러를 해결할 수 있다.
type Person = {
name: string;
age: number;
};
let person: Person = {}; // ❌ error!
person.name = "";
person.age = 23;
Person 타입으로 선언된 person 을 빈객체 {}
로 초기화 하고
이후에 값을 넣어주려고 위와 같이 사용하면 에러가 발생한다.
( name
과 age
는 필수값이기 때문에 error ! )
type Person = {
name: string;
age: number;
};
let person = {} as Person; // ✅ OK
person.name = "";
person.age = 23;
이러한 경우에는 빈 객체 {}
를 Person
타입이라고 타입 단언을 해주면 에러가 사라진다.
앞에서 설명한 초과 프로퍼티 에러도 해결할 수 있다.
type Dog = {
name: string;
color: string;
};
let dog: Dog = {
name: "돌돌이",
color: "brown",
breed: "진도", // 초과 프로퍼티 ( 원래는 error! )
} as Dog
하지만 모든 경우에서 타입 단언을 사용할 수 있는 것은 아니다.
타입 단언의 경우 변수 = Value as Type
문법으로 사용한다.
이 때, Value 가 Type 의 부모타입
이거나 서브타입
인 경우에만 사용이 가능하다.
let num1 = 10 as never; // ✅
let num2 = 10 as unknown; // ✅
let num3 = 10 as string; // ❌ error!
never
는 모든 타입의 자식타입이고, unknown
은 모든 타입의 부모타입니다.
Union Type 으로 선언되었을 때, 타입과 맞지 않는 함수를 사용 할 경우 에러가 발생할 수 있다.
function func(value: number | string) {
// Type이 정해지지 않음
value.toFixed() // ❌ error!
value.toUpperCase() // ❌ error!
}
이때 타입 가드
를 사용해서 특정 타입임을 보장해주어야 한다.
typeof
, instanceof
, in
을 사용해서 타입을 보장하는 방법에 대해 알아보자!
typeof A === B
: A의 타입이 B인지 확인A instanceof B
: A가 B의 요소인지 확인한다.Class
가 와야한다.A in B
: A 프로퍼티가 B에 있는지를 확인한다.null
이나 undefined
값이 들어오면 안된다.type Person = {
name: string;
age: number;
};
function func(value: number | string | Date | null | Person) {
if (typeof value === "number") {
// number 타입인 경우에만 실행
console.log(value.toFixed());
} else if (typeof value === "string") {
// string 타입인 경우에만 실행
console.log(value.toUpperCase());
} else if (value instanceof Date) {
//Date 타입인 경우에만 실행
console.log(value.getTime());
} else if (value && "age" in value) {
// value 에 age 프로퍼티가 있는 경우에만 실행.
// value 는 null or undefined 가 오면 완되므로 'value &&' 추가
console.log(`${value.name}은 ${value.age}살 입니다`)
}
}
if(value instanceof Person)
을 사용하지 못하는 이유는 Person 이 Class 가 아닌 Type이기 때문이다.