👌

TypeScript初見殺しを乗り越えようリターンズ

2023/09/26に公開
2

基礎をガッツリやってからフレームワークを触る人よりそうでない方が多いのではないでしょうか。私もその一人です。たまになんだこれなんでこんな書き方してるの?って時ありますよね。

というわけでTypeScript初見殺しを乗り越えようリターンズやります

1. ユーティリティ型(Partial)

  • サンプルコード:
    type PartialPoint = Partial<{ x: number, y: number }>;
    const point: PartialPoint = { x: 1 };
    
  • 解説: Partial を使うと、オブジェクトの一部だけを指定できます。例えば、2D座標を表すオブジェクトがあるとき、x 座標だけを先に設定して、y 座標は後から設定する、といったケースで便利です。

2. マッピング型(Readonly)

  • サンプルコード:
    type ReadonlyPoint = Readonly<{ x: number, y: number }>;
    const readonlyPoint: ReadonlyPoint = { x: 1, y: 2 };
    
  • 解説: Readonly を使うと、オブジェクトのプロパティを変更できなくなります。例えば、一度設定した座標を変更させたくない場合に使用します。

3. オプショナルとnull

  • サンプルコード:
interface Point {
  x: number;
  y?: number | null;
}

const calculateDistance = (point: Point) => {
  return point.x + (point.y ?? 0) + ' meters';
}

console.log(calculateDistance({ x: 10, y: 20 })); // Output: "30 meters"
console.log(calculateDistance({ x: 10 }));        // Output: "10 meters"
console.log(calculateDistance({ x: 10, y: null })); // Output: "10 meters"
console.log(calculateDistance({ x: 10, y: undefined })); // Output: "10 meters"

interface Point: Point インターフェースでは、x が必須プロパティで、y がオプショナルかつnullを許容するように型定義されています(y?: number | null)。

calculateDistance 関数: この関数は、Point インターフェースに基づいたオブジェクトを引数として受け取ります。関数内で、x の値と y の値(もしあれば)を足し合わせて、その結果に ' meters' を追加しています。

Nullish Coalescing(??): point.y ?? 0 という式があります。この式により、point.y が null または undefined の場合には 0 が使用されます。

関数の呼び出し: いくつかの異なるケースで関数を呼び出しています。これにより、y が null、undefined、または省略された場合でも関数が正しく動作することが確認できます。

y?: number | null;としないと型定義チェックが許してくれません

const z?: number = null;

定数にオプショナルを使うことはできません
ご指摘いただいた方ありがとうございます

4. メタプログラミング(keyof)

  • サンプルコード:
    type Keys = keyof { x: number, y: number };
    
  • 解説: keyof を使うと、オブジェクトのキー(プロパティ名)を取得できます。例えば、オブジェクトの各プロパティに順番にアクセスしたい場合に使用します。

5. コンフィグとトランスパイル

  • サンプルコード:
    // tsconfig.json
    {
      "compilerOptions": { "strict": true }
    }
    
  • 解説: tsconfig.json で厳格モードを有効にすると、より厳密な型チェックが行われます。これにより、プログラムのバグを早期に発見できます。

6. スプレッド構文

  • サンプルコード:
    const arr1 = [1, 2];
    const arr2 = [3, 4];
    const combinedArr = [...arr1, ...arr2];
    
  • 解説: スプレッド構文を使うと、2つの配列を簡単に結合できます。例えば、ショッピングカートに新しい商品を追加する場合などに使用します。

個人的にユーティリティ型とマッピング型が初見で謎でしたw
オプショナルはこっちが?なんだが??
スプレッド構文はなんか言いたいことあるんか?なんて思ったり
色々と初見殺しですが慣れます。
スタバの注文みたいなもんです(?)

おまけ

型の不整合を解決しよう

何人のフロント開発を苦しめてきたのでしょうww
簡単な例をあげていきます

  • サンプルコード:
    interface Point {
      x: number;
      y: number;
    }
    
  • 解説: Point というインターフェースを定義しています。このインターフェースは、xy という数値型のプロパティを持つオブジェクトを表します。

型の不整合のある関数

  • サンプルコード:
    function calculateDistance(point: Point) {
      return point.x + point.y + ' meters';
    }
    const distance = calculateDistance({ x: 1, y: '2' }); // Type Error
    
  • 解説: calculateDistance 関数は、Point 型のオブジェクトを引数に取ります。しかし、yに文字列を渡しているため、型エラーが発生します。

こうすると警告が消えます

  • サンプルコード:
    function fixedCalculateDistance(point: Point) {
      return point.x + point.y + ' meters';
    }
    const fixedDistance = fixedCalculateDistance({ x: 1, y: 2 });
    
  • 解説: fixedCalculateDistance 関数は、型の不整合を修正したバージョンです。正しくPoint 型のオブジェクトを引数に渡しています。

出力結果

  • サンプルコード:
    console.log(fixedDistance); // Output: '3 meters'
    
  • 解説: 修正後の関数を使用して、距離を計算し、その結果を出力しています。

Discussion

udonmaruudonmaru

ご指摘ありがとうございます!
大変勉強になりました..!