🫧 문제
객체 유형에서 인덱스 시그니처를 제외하는 RemoveIndexSignature<T>를 구현하세요
type Foo = {
[key: string]: any
foo(): void
}
type A = RemoveIndexSignature<Foo> // expected { foo(): void }
🛠️ 테스트 케이스
type Foo = {
[key: string]: any
foo(): void
}
type Bar = {
[key: number]: any
bar(): void
0: string
}
const foobar = Symbol('foobar')
type FooBar = {
[key: symbol]: any
[foobar](): void
}
type Baz = {
bar(): void
baz: string
}
type cases = [
Expect<Equal<RemoveIndexSignature<Foo>, { foo(): void }>>,
Expect<Equal<RemoveIndexSignature<Bar>, { bar(): void; 0: string }>>,
Expect<Equal<RemoveIndexSignature<FooBar>, { [foobar](): void }>>,
Expect<Equal<RemoveIndexSignature<Baz>, { bar(): void; baz: string }>>,
]
🎱 정답
type RemoveIndexSignature<T, P=PropertyKey> = {
[K in keyof T as P extends K? never : K extends P ? K : never]: T[K]
}
💭 해설
1. P = PropertyKey에서 PropertyKey키는 타입스크립트에서 모든 프로퍼티 키를 나타내는 내장 타입입니다.
- string : 문자열로 된 프로퍼티 키
- number : 숫자로 된 프로퍼티 키
- symbol : 심볼로 된 프로퍼티 키
일반적으로 PropertyKey는 인덱스 시그니처를 제거하거나 프로퍼티 접근을 일반화하는 등의 작업에서 사용됩니다. PropertyKey를 사용하면 모든 유형의 프로퍼티 키에 일반화된 작업을 수행할 수 있습니다.
예시 1:
function logProperty(obj: any, key: PropertyKey) {
const value = obj[key];
console.log(`${key}: ${value}`);
}
const person = {
name: 'John',
age: 30,
[Symbol('id')]: 'abc123'
};
logProperty(person, 'name'); // name: John
logProperty(person, 'age'); // age: 30
logProperty(person, Symbol('id')); // [Symbol(id)]: abc123
logProperty obj 객체와 key 프로퍼티 키를 받아 해당 프로퍼티의 값을 출력하는 역할을 합니다. PropertyKey는 문자열, 숫자, 심볼로 된 프로퍼티 키를 모두 다룰 수 있기 때문에 logProperty 함수를 호출할 때 다양한 프로퍼티 키를 전달할 수 있습니다.
예시 2:
type MyType = {
[key: PropertyKey]: number;
specialKey: string;
};
function getValue(obj: MyType, key: PropertyKey) {
if (typeof key === 'string') {
return obj.specialKey;
} else {
return obj[key];
}
}
const obj: MyType = { specialKey: 'value', 123: 456 };
console.log(getValue(obj, 'specialKey')); // 'value'
console.log(getValue(obj, 123)); // 456
2. [K in keyof T as P extends K? never : K extends P ? K : never]: T[K]
keyof T : T의 모든 프로퍼티 키의 유니온 타입
as : 이후에 작성된 타입을 keyof T 에 적용
PextendsK?never : P가 K의 서브 타입일 경우 (P가 K를 포함하는 경우), 해당 키는 제외된다.
K extends P ? K : never : K가 P의 서브타입일 경우(K가 P를 포함하는 경우), 해당 키는 포함된다. K 타입은 그대로 유지
'TypeScript' 카테고리의 다른 글
[Type-Challenges] 296. Permutation (0) | 2023.06.20 |
---|---|
[Type-Challenges] 119. ReplaceAll (0) | 2023.06.13 |
[Type-Challenges] 116. Replace (0) | 2023.06.13 |
[Type-Challenges] 110.Capitalize (0) | 2023.06.13 |
[Type-Challenges] 18. Trim (0) | 2023.06.13 |