0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Type Challenges 中級編14: ObjectEntries, Shift, Tuple to Nested Object

はじめに

GitHubのtype-challengesリポジトリは、TypeScript型システムの理解を深めるための型クイズ問題集です。高品質な型を作成することで、バグを減らし、プロジェクトの保守性を向上させることができます。今回も中級編から3つの問題に挑戦します。

1. ObjectEntries

この課題では、TypeScriptのオブジェクト型をキーと値のペアのタプルに変換する型を実装します。これはJavaScriptの Object.entries の型版です。

interface Model {
  name: string;
  age: number;
  locations: string[] | null;
}

type ModelEntries = ObjectEntries<Model>; // ['name', string] | ['age', number] | ['locations', string[] | null];

私の回答

type ObjectEntries<T> = {
  [K in keyof T]-?: [K, T[K]]
}[keyof T];

解き方

  • ObjectEntries 型は、オブジェクトの各プロパティキーに対して、そのキーと対応する値のペアを生成するマッピングを作成します。
  • 最終的に、各ペアのユニオン型を返します。

このようにして、オブジェクトのすべてのプロパティをキーと値のペアのタプルとして取得することができます。

早速前回学んだ-?が役立ちましたね!

2. Shift

この課題では、配列の先頭要素を削除した新しい配列型を返す型を実装します。これはJavaScriptの Array.shift の型版です。

type Result = Shift<[3, 2, 1]>; // [2, 1]

私の回答

type Shift<T extends Array<unknown>> = T extends [infer _, ...infer Rest] ? Rest : [];

解き方

  • Shift 型は、ジェネリック型 T が配列であり、その配列が非空の場合に先頭要素を除いた残りの配列を返すようにします。
  • infer キーワードを使用して先頭要素と残りの要素を抽出します。

このようにして、配列の先頭要素を削除した新しい配列型を作成することができます。

3. Tuple to Nested Object

この課題では、文字列のタプル型 T と任意の型 U を受け取り、タプルをネストされたオブジェクト型に変換する型を実装します。
:::note alert
いや急に簡単?inferさえできればできる。
:::

type A = TupleToNestedObject<['a'], string>; // {a: string}
type B = TupleToNestedObject<['a', 'b'], number>; // {a: {b: number}}
type C = TupleToNestedObject<[], boolean>; // boolean. if the tuple is empty, just return the U type

私の回答

type TupleToNestedObject<T, U> = 
  T extends [infer F, ...infer Rest] ? { [K in F & string]: TupleToNestedObject<Rest, U> } : U;

解き方

  • TupleToNestedObject 型は、タプル T が非空である限り、最初の要素 F をキーとし、そのキーの値が残りのタプル Rest をネストしたオブジェクト型となるように再帰的に処理します。
  • タプルが空の場合は、型 U を返します。

このようにして、タプルを元にネストされたオブジェクト型を生成することができます。

{ [K in F & string]: TupleToNestedObject<Rest, U> }
(Fは文字列リテラル)
でオブジェクトを作れることも覚えておこう。

まとめ

これらの課題を通じて、TypeScriptの型システムに対する理解が深まり、複雑な型操作のスキルが向上します。特に、タプルや配列の操作、オブジェクト型のプロパティの操作に関する知識を強化できます。ぜひ、これらの課題に挑戦して、型の理解を深めてください。

参考記事

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?