질문 배경
TypeScript는 처음부터 객체의 엄격한 타입화를 위해 설계되었고 JavaScript에서 예측 가능한 코드를 작성하는 데 중점을 두었습니다. 객체의 속성에 대한 안전한 접근을 보장하기 위한 도구 중 하나가 TypeScript 2.1에서 등장한 keyof 연산자입니다. 이 연산자는 선언된 객체 타입에서 사용 가능한 문자열(및 심볼) 키의 집합을 나타내는 타입을 생성할 수 있게 해줍니다.
문제점
순수 JavaScript에서는 객체의 속성을 어떤 문자열로든 요청할 수 있으며, 오류가 발생하면 undefined 또는 실행 중에만 발견되는 오류가 발생합니다. 엄격한 타입화가 없으면 오타를 내거나 리팩토링 중에 키 문자열 업데이트를 잊기 쉽습니다. 또한 특정 객체나 타입의 유효한 키만 허용하는 함수를 작성해야 하는 경우가 많습니다.
해결책
keyof 연산자는 타입의 모든 키로부터 유니온 타입을 생성합니다. 이를 통해 허용된 키를 제한하고 API의 안전성을 높이며(예: getter/setter 함수의 경우) 범용 유틸리티 타입을 만들 수 있습니다.
코드 예시:
type User = { name: string; age: number; active: boolean }; type UserKey = keyof User; // "name" | "age" | "active" function getProp<T, K extends keyof T>(obj: T, key: K): T[K] { return obj[key]; } const user: User = { name: 'Tom', age: 33, active: true }; const age = getProp(user, 'age'); // age는 number 타입
주요 특징:
배열에서 keyof가 반환하는 것은 무엇이며 인덱스를 얻을 수 있습니까?
배열에 대해 keyof는 배열이 실제로 JavaScript에서 객체로서 보유하고 있는 키 타입을 반환합니다. 일반적으로 인덱스 문자열과 배열의 특별한 속성이 포함됩니다.
코드 예시:
type A = keyof number[]; // "length" | "toString" | "pop" | ... | number
keyof가 유니온 타입의 키를 반환할 수 있습니까?
네, 유니온 타입의 keyof는 두 객체의 키 교차 집합을 반환하며, 합집합이 아닙니다.
코드 예시:
type A = {a: string, b: number } type B = {b: number, c: boolean } type C = keyof (A | B); // "b"
객체 속성이 선택적일 경우 어떻게 됩니까? keyof는 "?"를 지원합니까?
네, 선택적 속성도 결과 키 타입에 포함되지만, 이는 런타임에서 객체에 속성이 반드시 존재해야 한다는 것을 의미하지는 않습니다.
코드 예시:
type D = { a: string; b?: number }; type DK = keyof D; // "a" | "b"
keyof 대신 상수 문자열을 사용하는 것은 타입 손실입니다.keyof가 합집합을 반환한다고 생각하는 것은 잘못된 것입니다.keyof가 명시적으로 선언된 키만 고려되고 상속된 키는 무시된다고 예상하는 것은 잘못된 것입니다.getProperty(obj, key) 함수를 문자열 타입의 키로 작성하고 존재하지 않는 키를 호출할 때, 오류는 런타임에만 발생합니다.
장점:
단점:
제네릭을 사용: getProperty<T, K extends keyof T>()에서 key 타입은 구조의 키로 엄격하게 제한됩니다.
장점:
단점: