0Pricing
TypeScript Academy · レッスン

型レベルの比較

数値を完全に型レベルで比較します。

「型レベルの比較」はCoddyKit上の無料TypeScript Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはTypeScript Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 TypeScript Academyコースには全4レッスンが含まれています。

数値を比較する

数値リテラル型を比較するには、ここでもタプルを利用します。考え方は、両方の数値を同じペースで縮め、どちらが先に0になるかを確認することです。先に空のタプルになった方が小さい数値です。

type BuildTuple<N extends number, Acc extends unknown[] = []> =
  Acc["length"] extends N ? Acc : BuildTuple<N, [...Acc, unknown]>;

リテラルの等価性

数値リテラルの等価性は、相互の代入可能性を使って判定します。2つのリテラルは、互いに一方が他方を拡張するとき等しくなります。タプルでラップすると、ユニオン型による予期しない挙動を避けられます。

type NumEquals<A extends number, B extends number> =
  [A] extends [B] ? ([B] extends [A] ? true : false) : false;

type X = NumEquals<3, 3>; // true
type Y = NumEquals<3, 4>; // false

縮小による大なり比較

A > Bの場合、両方の数値に対応するタプルを構築し、1ステップごとにそれぞれから要素を1つ削除します。Bが先に空になり、その間Aに要素が残っていれば、Aの方が大きいことになります。

type GreaterThan<A extends number, B extends number> =
  BuildTuple<A> extends [...BuildTuple<B>, unknown, ...unknown[]]
    ? true : false;

type X = GreaterThan<5, 3>; // true
type Y = GreaterThan<3, 5>; // false

パターンの読み方

[...BuildTuple<B>, unknown, ...unknown[]]というパターンは、「長さBのプレフィックスに続いて、少なくとももう1つの要素がある」という意味です。Aがこのパターンに適合すれば、AはBより要素数が多く、したがってA > Bです。

type A = GreaterThan<4, 4>; // false (no extra element)
type B = GreaterThan<6, 2>; // true

小なり比較

LessThanは、引数の順序を入れ替えたGreaterThanにすぎません。改めて導出するのではなく、再利用しましょう。

type LessThan<A extends number, B extends number> =
  GreaterThan<B, A>;

type X = LessThan<3, 5>; // true
type Y = LessThan<5, 3>; // false

以上の比較

比較と等価性を組み合わせます。A >= Bは、A > BまたはA == Bのときに真になります。

type Gte<A extends number, B extends number> =
  GreaterThan<A, B> extends true
    ? true
    : NumEquals<A, B>;

type X = Gte<5, 5>; // true
type Y = Gte<3, 5>; // false

再帰による比較

別の方法として、どちらか一方が0になるまで両方をデクリメントして比較できます。これは、どちらが先に0になるかで小さい方を判定するという、同時進行の考え方を明確に示します。

type Cmp<A extends number, B extends number> =
  A extends 0
    ? (B extends 0 ? "eq" : "lt")
    : B extends 0
      ? "gt"
      : Cmp<Dec<A>, Dec<B>>;

type X = Cmp<3, 5>; // "lt"

Dec への依存

再帰による方法には、前のレッスンで扱ったDecが必要です。各ステップで両側から印を1つずつ削除します。両方が0になれば等しく、一方だけが0なら、もう一方の方が大きいことになります。

type Dec<N extends number> =
  BuildTuple<N> extends [unknown, ...infer R] ? R["length"] : 0;

等価性と代入可能性

注意が必要です。number extends numberは真ですが、これはリテラルの等価性ではありません。ここでの比較は3や5のような具体的なリテラル型を前提としており、広いnumber型は対象としていません。

type A = NumEquals<3, 3>;          // true
type B = 3 extends number ? 1 : 0; // 1 (assignability, not equality)

ソートキーを構築する

比較を使うと、順序付けのルールを型として表現できます。たとえば、2つの数値からなるタプルが昇順に並んでいるかどうかを、型レベルで判定できます。

type IsSorted<A extends number, B extends number> =
  GreaterThan<A, B> extends true ? false : true;

type X = IsSorted<2, 5>; // true
type Y = IsSorted<5, 2>; // false

用途を選んで使う

比較には再帰のコストがかかります。小さく範囲が限定された値(インデックスや固定上限など)の検証には適していますが、汎用的な数値ライブラリではありません。オペランドは小さく保ち、完全な同時進行の再帰より浅いプレフィックスパターン形式を優先しましょう。

type A = GreaterThan<9, 4>; // true (cheap, prefix pattern)

理解度チェック

型レベルの比較について、理解度を確認しましょう。

まとめ

これで、型システム上で数値を順序付けられるようになりました。

  • リテラルの相互代入可能性による等価性。
  • B 長のプレフィックスと追加の要素によるGreaterThan。
  • LessThanは引数の順序を入れ替え、Gteは等価性を追加します。
  • 小さなリテラル型の数値で機能し、広いnumber型では機能しません。

次は、これらを実用的なユーティリティにします。

よくある質問

「型レベルの比較」レッスンは無料ですか?

はい。「型レベルの比較」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、TypeScript Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 TypeScript Academyコースには全4レッスンが含まれています。

「型レベルの比較」で何を学びますか?

数値を完全に型レベルで比較します。 ブラウザで直接実行するハンズオンコードでTypeScript Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

TypeScript Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのTypeScript Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。

「型レベルの比較」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このTypeScript Academyレッスンでコードを書いて実行できますか?

はい。すべてのTypeScript Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. タプルの長さによるカウント
  2. 型レベルの加算と減算
  3. 型レベルの比較
  4. 実践的な数値型ユーティリティ
← TypeScript Academyに戻る