Open2

プロを目指す人のためのTypeScript入門(ブルーベリー本)学習記録

キョーヤキョーヤ

2025/08/13 (251 〜 270P)

  • プリミティブ & プリミティブ→never型

  • 関数型同士のユニオン型を合成した際に、引数は反変の位置になるためインターセクション型。戻り値は共変の位置にあたるユニオン型になる

    type Human = { name: string }
    type Animal = { species: string }
    
    function getName(human: Human) {
        return human.name;
    }
    
    function getSpecies(animal: Animal) {
        return animal.species;
    }
    
    const mysteryFunc = Math.random() > 0.5 ? getName : getSpecies;
    

    引数が反変の位置ではないためエラー(HumanとAnimal両方のプロパティが無いため)

    const uhyo: Human = {
        name: "uhyo"
    }
    
    const cat: Animal = {
        species: "cat"
    }
    
    mysteryFunc(uhyo);
    mysteryFunc(cat);
    

    引数が反変の位置であるため通る

    const uhyo: Human & Animal = {
        name: "uhyo",
        species: "human"
    };
    
    const val = mysteryFunc(uhyo);
    console.log(val); // {name: "uhyo", species: "human"}
    
  • コンパイルオプション exactOptionalPropertyTypesについて

    有効 無効
    age: 123 ⭕️ ⭕️
    age: undefined ⭕️
    省略 ⭕️ ⭕️
  • リテラル型のwideningの条件

    • letで変数宣言した時
    const uhyo1 = "uhyo" // "uhyo型"
    let uhyou2 = uhyo1 // string型
    
    • ただし、リテラル型を明示的に注釈した際はwideningされない
    const uhyo3: "uhyo" = "uhyo" // "uhyo型"
    let uhyo4 = uhyo3 // "uhyo"型
    
    • オブジェクトリテラルの中
    const uhyo = {
      name: "uhyo",
      age: 26
    };
    
    uhyo.name = "john" // nameはstringにwideningされるので"uhyo"以外でも通る
    
キョーヤキョーヤ

2025/08/16

Indexed Access Types の実用的な使用例

本書の291Pに載っていた以下のコードについて(typeof names)[number]が理解できなかったので今回まとめてみました。

const names = ["uhyo", "John", "Taro"] as const;
type Name = (typeof names)[number];

1. 配列の要素の型を取得

const arr = ["a", "b", "c"] as const;
type Element = (typeof arr)[number]; // "a" | "b" | "c"

ポイント: [number] で配列の全要素の型をユニオン型として取得できます。配列の内容が変更されても型が自動的に更新されます。

2. オブジェクトの特定の値の型を取得

const obj = { x: 1, y: 2, z: 3 } as const;
type Value = (typeof obj)["x"]; // 1

ポイント: 特定のキーを指定して、その値のリテラル型を取得できます。

3. オブジェクトの全値の型を取得

const obj = { x: 1, y: 2, z: 3 } as const;
type Values = (typeof obj)[keyof typeof obj]; // 1 | 2 | 3

ポイント: keyof typeof obj でオブジェクトの全キーを取得し、それらを使って全値の型をユニオン型として取得できます。

4. タプルの特定の位置の型を取得

const tuple = ["hello", 42, true] as const;
type First = (typeof tuple)[0]; // "hello"
type Second = (typeof tuple)[1]; // 42

ポイント: 数値インデックスでタプルの特定の位置の型を取得できます。配列と異なり、位置ごとに異なる型を持つことができます。

共通の構文パターン

()[アクセスキー]
  • 配列: [number] で全要素
  • オブジェクト: [キー名] で特定の値、[keyof 型] で全値
  • タプル: [数値] で特定の位置

これらの例は、ブルーベリー本で学んだ基本的な型の知識を発展させて、より実用的な型操作を可能にする Indexed Access Types の威力を示していますね!