👌

配列とオブジェクトからの型生成

2025/01/16に公開

この記事の目的

配列とオブジェクトからの型生成について忘れがちなので、生成の方法をと細かい意味をまとめて記憶に留めることを目的としています。

配列からの型生成

const fruits = ['apple', 'banana', 'orange'] as const

// fruits の型
type Fruits = (typeof fruits)[number]
// "apple" | "banana" | "orange"
const Users = [
  {
    id: 1,
    name: 'John',
  },
  {
    id: 2,
    name: 'Doe',
  },
  {
    id: 3,
    name: 'Smith',
  },
] as const

// Users の id の型
type UsersId = (typeof Users)[number]['id']
// 1 | 2 | 3

// Users の name の型
type UsersName = (typeof Users)[number]['name']
// 'John' | 'Doe' | 'Smith'

オブジェクトからの型生成

const obj = {
  a: {
    id: 1,
    name: 'John',
  },
  b: {
    id: 2,
    name: 'Doe',
  },
  c: {
    id: 3,
    name: 'Smith',
  },
} as const

// obj の id の型
type ObjId = keyof typeof obj
// 'a' | 'b' | 'c'

// obj の name の型
type ObjName = (typeof obj)[ObjId]['name']
// 'John' | 'Doe' | 'Smith'

typeof の役割

typeof は、変数や値からその型を取得するためのキーワードです。

通常、JavaScriptでの typeof は値の型を「文字列」として取得するために使われます(例: "number", "string")。
一方、TypeScriptの typeof は、変数やオブジェクトの型情報を取得するために使われます

fruits の型をリテラル型で取得する

const fruits = ['apple', 'banana', 'orange'] as const;

// この時点で `typeof fruits` は型を取得する
type FruitsArrayType = typeof fruits;
// 型: readonly ['apple', 'banana', 'orange']

fruits の型をユニオン型で取得する

const fruits = ['apple', 'banana', 'orange'] as const;

// fruits の型
type Fruits = (typeof fruits)[number];
// 'apple' | 'banana' | 'orange'
  1. typeof fruits について

    • typeof fruits は変数 fruits の型情報を取得します。
    • as const を付けているため、fruits の型はリテラル型になります。
    • つまり、typeof fruits は型 readonly ['apple', 'banana', 'orange'] を返します。
  2. インデックスアクセス型 ([number])

    • readonly ['apple', 'banana', 'orange'] は配列型です。
    • 配列型に対して [number] と指定すると、配列内の要素の型を取得します。
    • この場合、'apple' | 'banana' | 'orange' というユニオン型が得られます。

Users の id 型をユニオンで取得する

const Users = [
  { id: 1, name: 'John' },
  { id: 2, name: 'Doe' },
  { id: 3, name: 'Smith' },
] as const;

// Users の id の型
type UsersId = (typeof Users)[number]['id'];
// 型: 1 | 2 | 3
  1. typeof Users について

    • typeof Users は、変数 Users の型情報を取得します。
      as const を使っているので、Users の型は次のように解釈されます:
    readonly [
      { readonly id: 1, readonly name: 'John' },
      { readonly id: 2, readonly name: 'Doe' },
      { readonly id: 3, readonly name: 'Smith' }
    ]
    
  2. インデックスアクセス型 ([number])

    • 配列型に対して [number] を指定すると、配列内のすべての要素の型を取得します。
    • この場合、typeof Users[number] は以下の型を表します:
    { readonly id: 1, readonly name: 'John' }
    | { readonly id: 2, readonly name: 'Doe' }
    | { readonly id: 3, readonly name: 'Smith' }
    
  3. さらに ['id'] を指定

    • 各オブジェクトの id プロパティの型を取り出します。
    • 結果として、1 | 2 | 3 のユニオン型が得られます。

keyof の役割

keyof は、オブジェクトのすべてのキー(プロパティ名)を型として取得するために使われます。
ポイント: keyof はオブジェクト型の「キー名」をユニオン型('a' | 'b' | 'c')として表現します。

const obj = {
  a: 1,
  b: 2,
  c: 3,
};

// `keyof` を使うと、`obj` のキーである 'a', 'b', 'c' を取得
type Keys = keyof typeof obj;
// 型: 'a' | 'b' | 'c'

その typeof は JavaScript or TypeScript

  • typeof

    • JavaScriptにも存在するが、TypeScriptでは「型情報を取得する」ための用途として拡張された。
    • TypeScriptの typeof は、コンパイル時に変数やオブジェクトの型情報を取得する。
    • JavaScriptの typeof は、実行時に値の型を文字列で返す。
  • keyof

    • TypeScript専用の機能。
    • オブジェクト型の「すべてのキー名」をユニオン型として取得する。

まとめ

最近は、型を作るときはほぼCopilotを使用しているので、実際に自分で書くときに「あれ?どうだったっけ」となることがあったので、記憶に定着されるためにまとめました。

Discussion