typeof 타입 연산자

typeof 타입 연산자 (Typeof Type Operator)

TypeScript에서 타입을 다루다 보면 '이 값이 가진 타입'을 그대로 재사용하고 싶을 때가 있어요. 그때 쓰는 게 바로 typeof 타입 연산자예요. 값이 있는 곳에서는 익숙한 typeof가, 타입 위치에서는 전혀 다른 역할을 한다는 걸 함께 살펴볼게요.

출처: TypeScript 핸드북 - Typeof Type Operator

typeof 타입 연산자

자바스크립트에는 이미 표현식(expression) 컨텍스트에서 쓸 수 있는 typeof 연산자가 있어요.

// Prints "string"
console.log(typeof "Hello world");

TypeScript는 타입(type) 컨텍스트에서 쓸 수 있는 typeof 연산자를 추가하는데, 변수나 프로퍼티의 타입 을 가리키는 데 사용합니다.

let s = "hello";
let n: typeof s;
//  ^?

기본 타입에는 이게 그리 유용해 보이지 않지만, 다른 타입 연산자와 결합하면 typeof로 많은 패턴을 편리하게 표현할 수 있어요. 예를 들어 미리 정의된 타입 ReturnType<T>를 먼저 살펴볼게요. 이 타입은 함수 타입 을 받아 그 반환 타입을 만들어 냅니다.

type Predicate = (x: unknown) => boolean;
type K = ReturnType<Predicate>;
//   ^?

함수 이름에 ReturnType을 쓰려고 하면, 교훈적인 에러를 보게 돼요.

// @errors: 2749
function f() {
  return { x: 10, y: 3 };
}
type P = ReturnType<f>;

값(values)타입(types) 은 같은 게 아니라는 점을 기억하세요. f라는 값 이 가진 타입 을 가리키려면 typeof를 사용합니다.

function f() {
  return { x: 10, y: 3 };
}
type P = ReturnType<typeof f>;
//   ^?

제약 사항 (Limitations)

TypeScript는 typeof를 사용할 수 있는 표현식의 종류를 의도적으로 제한해요.

구체적으로, typeof는 식별자(identifier, 즉 변수 이름)나 그 프로퍼티에만 사용하는 것이 합법적이에요. 이는 실행된다고 생각하지만 실제로는 실행되지 않는 코드를 쓰는 혼란스러운 함정을 피하는 데 도움이 돼요.

// @errors: 1005
declare const msgbox: (prompt: string) => boolean;
// type msgbox = any;
// ---cut---
// Meant to use = ReturnType<typeof msgbox>
let shouldContinue: typeof msgbox("Are you sure you want to continue?");

더 알아보기 (Learn more)