Open25

type-challenges

shikatanshikatan

14 - First of Array

回答 1

type First<A extends unknown[]> = A extends [] ? never : A[0]

回答 2

type First<A extends unknown[]> = A extends [infer B, ...unknown[]] ? B : never
shikatanshikatan

533 - Concat

回答

type Concat<T extends readonly unknown[], U extends readonly unknown[]> = [...T, ...U]
shikatanshikatan

898 - Includes

回答

type Includes<T extends readonly any[], U> = T extends [infer A, ...infer B]
	? (<C>() => C extends A ? 1 : 0) extends (<C>() => C extends U ? 1 : 0) ? true : Includes<B, U>
	: false
shikatanshikatan

3312 - Parameters

回答

type MyParameters<T extends (...args: any[]) => unknown> = T extends (...args: infer A) => unknown ? A : never
shikatanshikatan

3 - Omit

回答

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

8 - Readonly 2

回答

type MyReadonly2<T, K extends keyof T = keyof T> =
	& { readonly [A in K]: T[A] }
	& { [A in keyof T as A extends K ? never : A]: T[A] }
shikatanshikatan

9 - Deep Readonly

回答

type DeepReadonly<T> = { readonly [A in keyof T]: T[A] extends (...args: any[]) => unknown ? T[A] : DeepReadonly<T[A]> }

オブジェクトと配列のみ readonly にしたい。

用意されているケースの () => 22 以外の型は mapped type でオブジェクトに変換されない。

This mapped type returns a primitive type, not an object type.
https://github.com/microsoft/TypeScript/wiki/FAQ#common-bugs-that-arent-bugs

() => 22 だけ除外する mapped type でオブジェクトと配列のみ readonly を表現できた。

shikatanshikatan

12 - Chainable Options

回答

type Chainable<A = object> = {
	option<B extends string, C>(
		key: B extends keyof A ? never : B,
		value: C,
	): Chainable<{ [D in keyof A as D extends B ? never : D]: A[D] } & { [_ in B]: C }>
	get(): A
}
shikatanshikatan

20 - Promise.all

回答

declare function PromiseAll<A extends unknown[]> (
	values: [...A],
): Promise<{ [B in keyof A]: A[B] extends Promise<infer C> | infer C ? C : never }>

配列ではなくタプルとして推論させるために A ではなく [...A] とする。
A[B] だと union distribution にならないので対応が必要。