keyof
operator는 객체의 타입을 받아서 그 키의 string이나 number의 literal union을 만듬.
아래 type P는 'x'|'y'
타입이랑 같음.
type Point = { x: number; y: number };
type P = keyof Point;
// P의 타입은 keyof Point임.
// Point의 키인 x와 y라는 뜻임.
아래를 보면 좀 더 명확해지는데 Type은 obejct
타입을 받는거고 Key는 객체의 키가 되는거라서 Key는 obj의 키만 받을 수 있음.
function getProperty<Type, Key extends keyof Type>(obj: Type, key: Key) {
return obj[key];
}
let x = { a: 1, b: 2, c: 3, d: 4 };
getProperty(x, "a");
getProperty(x, "m"); // error: Argument of type '"m"' is not assignable to parameter of type '"a" | "b" | "c" | "d"'.
타입이 string
이나 number
*index signature를 가지고있으면 keyof
는 그 타입을 리턴해줌.
/* { [k: string]: boolean } 이거는 앞의 키 string이고 value가 boolean 타입이라는 뜻임.
[]는 key-value 쌍이 여러개 일 수 있다는 뜻으로 쓰는거임.
그냥 object로 해버리면 아래처럼 value type을 지정못하기 때문에 이렇게함.
const map1: object = {
foo: 'a',
bar: 'b',
}
*/
type Arrayish = { [n: number]: unknown };
type A = keyof Arrayish;
// A는 아래와 같음
type A = number
type Mapish = { [k: string]: boolean };
type M = keyof Mapish;
// M은 아래와 같음
type M = string | number
타입 M
이 string | number
인 이유는 자바스크립트 오브젝트 키가 스트링으로 강요되기 때문에 obj[0]
은 obj['0']
과 같아서임.
타입 스크립트 객체는 다른 객체의 참조를 문자열로 할 수 있음.
let indexedArray1: {[key: string]: number[]} = {
foo: [123, 456],
bar: [456]
}
console.log(indexedArray1['foo'])
console.log(indexedArray1.foo)
// Output:
[ 123, 456 ]
[ 123, 456 ]