TypeScript를 사용하다보면 typeof
연산자(JavaScript에도 존재하는)를 자주 마주치게 된다. TypeScript에서 typeof
는 두 가지 문맥에서 사용된다.
- JavaScript의 런타임
typeof
연산자 - TypeScript의 타입 연산자로서의
typeof
1. JavaScript의 런타임 typeof 연산자
typeof
는 피연산자의 데이터 타입을 나타내는 문자열을 반환한다.
let value = "hello";
console.log(typeof value); // "string"
let number = 32;
console.log(typeof number); // "number"
let func = () => {};
console.log(typeof func); // "function"
반환되는 값은 JavaScript의 기본 데이터 타입 (boolean, number, bigint, string, symbol, null, undefined)과 function, object 이다.
2. TypeScript의 타입 연산자 typeof
TypeScript에서는 typeof
를 type
문맥에서도 사용할 수 있다. 이때는 역할이 달라진다.
const user = {
name: "John",
age: 30,
isAdmin: true
};
const v_user = typeof user; // object
type User = typeof user;
// 결과:
// type User = {
// name: string;
// age: number;
// isAdmin: boolean;
// }
위 예시의 v_user
는 const
키워드로 선언된 변수에서 사용됐다. 따라서 값이 할당되야 하므로 user
의 런타입 타입을 가리키는 'object'
를 반환한다. 하지만 type
키워드 뒤에서 사용된 typeof
는 타입스크립트의 타입을 반환한다.
typeof
는 값에서 타입을 추출할 때만 사용하도록 한다. 이미 타입인 것에서 사용할 때는 에러가 난다.
// 잘못된 사용
type MyString = string;
type Wrong = typeof MyString; // 오류!
// 올바른 사용
const myString = "hello";
type Correct = typeof myString; // string
typeof 활용
1. 배열에서 유니온 타입 추출
const colors = ["red", "green", "blue"] as const;
type Colors = typeof colors[number];
// type Colors = "red" | "green" | "blue"
2. 객체 타입 추출
// without as const
const config = {
endpoint: "api.example.com",
port: 3000
};
type Config = typeof config;
// type Config = {
// endpoint: string;
// port: number;
// }
// with as const
const config = {
endpoint: "api.example.com",
port: 3000
} as const;
type Config = typeof config;
// type Config = {
// readonly endpoint: "api.example.com";
// readonly port: 3000;
// }
as const
와 함께 사용하면 readonly
가 붙어서 추출된다.
3. 함수 타입 추출
유틸리티 타입 ReturnType
과 Parameters
를 활용하여 함수의 매개변수와 반환 타입을 추출할 수 있다.
function createUser(name: string, age: number) {
return { id: Date.now(), name, age };
}
type User = ReturnType<typeof createUser>;
// type User = {
// id: number;
// name: string;
// age: number;
// }
type Param = Parameters<typeof createUser>
// type Param = {
// name: string;
// age: number;
// }
🔎 참조