T에서 K 프로퍼티만 제거해 새로운 오브젝트 타입을 만드는 내장 제네릭 Omit<T, K>를 이를 사용하지 않고 구현하세요.
type MyOmit<T, K extends keyof T> = {
[R in keyof T as R extends K ? never : R]:T[R]
}
antfu는 다음과 같은 풀이를 제시했다
type MyExclude<A, B> = A extends B ? never : A;
type MyOmit<T, K extends keyof T> = { [S in MyExclude<keyof T, K>]: T[S] }
사실 내장 Exclude 타입과 MyExclude는 같다
이 방식은 새로운 예제인 readonly를 살려야 하는 예제에서는 사용할 수 없다
typeScript 4.1에서 나온 as 키워드를 사용하였다.
mapped type의 key 사용부분 에서 as를 사용하면 as 앞에 있는 타입을 as 뒤에서 새롭게 사용할 수 있다.(심지어 value부분의 타입을 정할 때에도)
type Tmp={
[R in keyof T as `R을 가지고 새로운 key 타입을 정의`]
: `이곳에서도 R을 사용할 수 있다`
}
그리고 새로운 타입을 정할 때, never가 들어가게 되면 그 키는 사용되지 않는다.
type Tmp={
[R in keyof T as never]
: `이곳에서 사용된 값은 의미가 없어진다(key 타입이 항상 never이기 때문에)`
}
왜 Exclude를 사용하면 되지 않을까?
나도 자세히는 모르겠지만, mapped type내에서 in keyof를 사용하면 readonly 속성이 살아있고,
in 뒤에 keyof가 아닌 다른 속성이 들어가면 readonly가 들어가지 않는 것 같다.
https://www.typescriptlang.org/docs/handbook/2/mapped-types.html