Open13

type-challenges【初級編】

yutake27yutake27

Pick

Pickを実装

解答

type MyPick<T, K extends keyof T> = {
  [key in K]: T[key]
}

extends keyof Tで引数の制約条件

タイプ

Index Signature

yutake27yutake27

Tuple To Object

タプルを受け取り、その各値のkey/valueを持つオブジェクトの型に変換する型を実装します。

解答

一瞬悩んだ

type TupleToObject<T extends readonly PropertyKey[]> = {
  [k in T[number]]: k
}

タイプ

Index Signature

yutake27yutake27

First of Array

配列の先頭要素取得

解答

type First<T extends any[]> = T extends [infer Head, ...any]
  ? Head
  : never

タイプ

配列の型推論

yutake27yutake27

Length of Tuple

配列の長さを取得

解答

type Length<T extends readonly any[]> = T['length']

タイプ

lengthを知っているかどうか

yutake27yutake27

Exclude

Excludeの実装

解答

type MyExclude<T, U> = T extends U ? never : T

タイプ

Union distributionの知識が一部必要

yutake27yutake27

Awaited

Promise ライクな型が内包する型を取得

解答

type MyAwaited<T> = T extends PromiseLike<infer U>
  ? U extends PromiseLike<any>
    ? MyAwaited<U>
    : U
  : never

タイプ

型推論と再帰

yutake27yutake27

If

条件値C、 Cが truthy である場合の戻り値の型T、Cが falsy である場合の戻り値の型Fを受け取るIfを実装します。 条件値C はtrueかfalseのどちらかであることが期待されますが、T と F は任意の型をとることができます。

解答

type If<C extends boolean, T, F> = C extends true ? T : F

タイプ

extends
他のでやっているのでやらなくても良いかも

yutake27yutake27

Concat

JavaScript のArray.concat関数を型システムに実装します。この型は 2 つの引数を受け取り、受け取ったイテレータの要素を順に含む新しい配列を返します。

解答

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

タイプ

スプレッド演算子

yutake27yutake27

Includes

JavaScriptのArray.include関数を型システムに実装します。この型は、2 つの引数を受け取り、trueやfalseを出力しなければなりません。

解答

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

タイプ

配列の型推論、再帰、Equal

初級で一番難しいかも

yutake27yutake27

Push

Array.pushのジェネリックバージョンを実装します。

解答

type Push<T extends any[], U> = [...T, U]

タイプ

スプレッド演算子

Concatでやっているので不要かも

yutake27yutake27

Unshift

Array.unshiftの型バージョンを実装します。

解答

type Unshift<T extends any[], U> = [U, ...T]

タイプ

スプレッド演算子

Concat, Pushでやっているので不要

yutake27yutake27

Parameters

組み込みの型ユーティリティParameters<T>を使用せず、Tからタプル型を構築する型を実装します。

解答

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

タイプ

関数のinfer