Open4

type challengeで得た知見まとめ

tacrewtacrew

再帰表現

type Includes<T extends readonly any[], U> = T extends [infer First,...infer Rest] ?
Equal<U,First> extends true ? true : Includes<Rest,U>
: false
tacrewtacrew

keyをneverにしてfilter out

type MyOmit<T, K extends keyof T> = {
  [key in keyof T as key extends K ? never : key]: T[key]
}
tacrewtacrew

arrayからtupleへの変換

declare function PromiseAll<T extends any[]>(values: readonly [...T]): Promise<{
  [key in keyof T]: T[key] extends Promise<infer R> ? R : T[key]
}>

解説参考
https://github.com/type-challenges/type-challenges/issues/3444#issuecomment-945072978

Thank you for your question. The reason why the array should be transformed to be a tuple is that a tuple type knows exactly how many elements it contains, and exactly which types it contains at specific positions, then we could construct a new tuple type from it.

About readonly [...V]

  1. Tuple can have rest elements, which have to be an array/tuple type, so we use [...V] to transfrom the type param to a tuple type.
declare function PromiseAll<V extends any[]>(values: [...V]): V
const a = PromiseAll([1, 2, Promise.resolve(3)])
type A = typeof a // Promise<[number, number, Promise<number>]>

// if not
declare function PromiseAll<V extends any[]>(values: V): V
const a = PromiseAll([1, 2, Promise.resolve(3)])
type A = typeof a // (number | Promise<number>)[]
  1. The params like[1, 2, 3] as const will be inferred with readonly tuple types, which won't be compatible with mutable tuple type, so we add the preffix readonly.
declare function PromiseAll<V extends any[]>(values: [...V]): V
const a = PromiseAll([1, 2, Promise.resolve(3)] as const) // error