[TypeScript] 타입으로 변환하기 typeof & keyof
📌 typeof 연산자
우리는 이미 자바스크립트에서 변수의 타입을 얻기 위해 typeof 연산자를 한 번 쯤은 사용해 봤을 것 입니다.
const num: number = 1;
const str: string = "Hello World";
console.log(typeof num); // number
console.log(typeof str); // string
타입스크립트에서도 typeof 연산자가 사용되는데, 다음 3가지 상황에서 사용될 수 있습니다.
1. 객체 데이터를 객체 타입으로 변환
2. 함수를 타입으로 변환
3. 클래스를 타입으로 변환
✅ 객체 데이터를 객체 타입으로 변환
객체 데이터에 대해 typeof 연산자를 사용하면, 해당 객체를 구성하는 타입 구조를 독립된 타입으로 가져와 사용할 수 있습니다.
const john = {
name: "John",
age: 20,
male: true,
};
type Person = typeof john;
// type Person = {
// name: string;
// age: number;
// male: boolean;
// }
const alice: Person = {
name: "Alice",
age: 20,
male: false
}
✅ 함수를 타입으로 변환
어떠한 함수를 타입으로 변환하여 재사용이 가능하도록 만들 수 있습니다.
function func(num: number, str: string): string {
return num.toString();
}
type Func_Type = typeof func;
// type Func_Type = (num: number, str: string) => string
const func2: Func_Type = (num: number, str: string): string => {
return str;
};
✅ 클래스를 타입으로 변환
클래스 자체가 객체 타입이 될 수 있으므로 typeof 연산자를 붙여주지 않고도 클래스의 타입을 가져올 수 있습니다.
또한 클래스의 인스턴스를 생성하는 함수의 매개변수에서 typeof 연산자를 사용하면, 해당 클래스에 해당하는 생성 시그니처(construct signature)를 얻을 수 있으므로 타입 검증이 가능합니다.
class User {
name: string;
age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
}
// typeof User: new (name: string, age: number) => User
// typeof 연산자를 통해 User 클래스에 해당하는 생성 시그니처(construct signature)
// 를 얻을 수 있으므로 타입 검증이 가능함
function createUser(Constructor: typeof User, name: string, age: number) {
const user = new Constructor(name, age);
return user;
}
type User_Type = User;
// type User_Type = { name: string, age, number }
const user1 = createUser(User, "john", 20);
const user2: User_Type = {
name: "john",
age: 20,
};
📌 keyof 연산자
keyof 연산자는 인덱싱 가능 타입의 속성 이름(속성 키)을 타입으로 사용할 수 있습니다.
즉, 인덱싱 가능 타입의 속성 이름들이 유니온 타입으로 적용됩니다.
인덱싱 가능 타입
arr[2]와 같이 '숫자'로 인덱싱 하거나, obj['name']과 같이 '문자'로 인덱싱 가능한 타입
interface Countries {
KR: "대한민국";
US: "미국";
}
type CountriesKey = keyof Countries;
// 'KR' | 'US'
let country: CountriesKey = "KR";
country = "US";
type CountriesValue = Countries[keyof Countries];
// '대한민국' | '미국'
📌 typeof & keyof 활용
typeof 와 keyof 를 사용하여 Enum 대체 상수 타입을 정의할 수 있습니다.
열거형 타입 Enum 에 대한 의견은 다양하지만, 여러가지 이유로 대부분 상수 타입을 쓰는 것을 권장하고 있습니다.
const Direction = {
Up: "up",
Down: "down",
Left: "left",
Right: "right",
} as const;
// typeof Direction = {
// readonly Up: "up";
// readonly Down: "down";
// readonly Left: "left";
// readonly Right: "right";
// }
// keyof typeof Direction = 'Up' | 'Down' | 'Left' | 'Right'
type DirectionType = (typeof Direction)[keyof typeof Direction];
// type DirectionType = "up" | "down" | "left" | "right"
const dir: DirectionType = 'down'
📚 참고
https://heropy.blog/2020/01/27/typescript/
https://velog.io/@surim014/5-very-useful-tricks-for-thetypescript-typeof-operator