型コンストラクターの定義
interfaceのルックアップとして型コンストラクターをエンコードします。
「型コンストラクターの定義」はCoddyKit上の無料TypeScript Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはTypeScript Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 TypeScript Academyコースには全4レッスンが含まれています。
型コンストラクターの命名
このエンコーディングでは、まず各型コンストラクターにURIと呼ばれる一意の文字列識別子を与えます。URIは、コンストラクターそのものを渡せない場所で、コンストラクターの代わりになるタグです。
type ArrayURI = "Array";
type OptionURI = "Option";
// Each container gets a unique string tagレジストリのインターフェース
引数Aに対して生成される具体的な型へ、各URIを対応付ける単一のインターフェースを用意します。このインターフェースがレジストリです。各キーはURIで、各値は解決された型です。
interface URItoKind<A> {
Array: Array<A>;
Option: A | null;
}
// URItoKind<number>["Array"] is number[]コンストラクターの検索
レジストリはURIをキーにしているため、コンストラクターの適用はインデックスアクセスになります。「Arrayにnumberを適用した型」を取得するには、レジストリをインデックスで参照します。
type ArrayOfNumber = URItoKind<number>["Array"]; // number[]
type OptionOfString = URItoKind<string>["Option"]; // string | nullURIS共用体
有効なコンストラクタータグの集合は、レジストリのキーそのものです。keyof URItoKind<unknown>によって、登録されているすべてのURIの共用体が得られます。これをURISと名付けます。
type URIS = keyof URItoKind<unknown>; // "Array" | "Option"宣言マージによるレジストリの拡張
TypeScriptには強力な機能があります。同じ名前のインターフェースはマージされます。ライブラリはこれを利用して、元の定義を編集せずに各モジュールから独自のコンテナをURItoKindへ追加します。
interface URItoKind<A> {
Tree: { value: A; children: Array<A> };
}
// Now URIS also includes "Tree"モジュール化されたコンテナ
宣言マージのおかげで、あるファイルで定義したコンテナをグローバルに登録できます。それをインポートしたコードは、そのURIを汎用的な抽象化で利用できます。fp-tsがOption、Either、Taskなどを追加する方法もまさにこれです。
// file a.ts
interface URItoKind<A> { Either: { left: A } | { right: A } }
// file b.ts can now reference the "Either" URIファントムキャリア
「どのコンストラクターか」を値レベルの型として渡すために、インスタンスはプロパティ(多くの場合はファントムフィールド)にURIを保持します。このフィールドが実際の値を保持することはありません。型システムのためにタグを記録するだけです。
interface HasURI<F extends URIS> {
readonly _URI: F;
}
// _URI records which constructor an instance is forURIと引数の組み合わせ
コンストラクターの適用には、URI Fと引数の型Aという2つの要素が必要です。これらを検索で組み合わせ、(F, A)からレジストリを通じて具体的な型を解決します。
type Apply<F extends URIS, A> = URItoKind<A>[F];
type A = Apply<"Array", number>; // number[]
type B = Apply<"Option", string>; // string | nullコンストラクターではなく文字列を使う理由
文字列を使うのは、TypeScriptが文字列リテラル型として保存・比較でき、文字列でレジストリをインデックスできるからです。コンストラクターであるArrayを型パラメーターとして保存することはできませんが、リテラル"Array"なら保存して検索できます。
type Tag = "Array";
type Resolved = URItoKind<boolean>[Tag]; // boolean[]検索が重要な一手
このインデックスアクセスURItoKind<A>[F]が、エンコーディングの核心です。実行できない型の適用F<A>を、合法的なレジストリ検索に変換します。次のレッスンでは、これをKind<F, A>として形式化します。
type Kind<F extends URIS, A> = URItoKind<A>[F];
type X = Kind<"Array", number>; // number[]準備のまとめ
これで必要な要素がそろいました。タグとしてのURI、タグと引数を具体的な型に対応付けるURItoKindレジストリ、タグの共用体であるURIS、そしてそれを拡張する宣言マージです。レジストリのインデックス参照によって、型の適用をシミュレートできます。
// URItoKind = registry, URIS = valid tags,
// URItoKind<A>[F] = "apply constructor F to A"クイックチェック
レジストリによるエンコーディングについての理解度を確認しましょう。
まとめ
文字列を使って型コンストラクターをエンコードする方法を学びました。
- 各コンストラクターには一意のURIタグを割り当てます。
URItoKind<A>はタグを具体的な型に対応付けます。URISはkeyofによるすべてのタグの共用体です。- 宣言マージによって、モジュールから新しいコンテナを登録できます。
次は、検索を軽量なKindパターンとしてまとめます。
よくある質問
「型コンストラクターの定義」レッスンは無料ですか?
はい。「型コンストラクターの定義」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、TypeScript Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 TypeScript Academyコースには全4レッスンが含まれています。
「型コンストラクターの定義」で何を学びますか?
interfaceのルックアップとして型コンストラクターをエンコードします。 ブラウザで直接実行するハンズオンコードでTypeScript Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
TypeScript Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのTypeScript Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。
「型コンストラクターの定義」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このTypeScript Academyレッスンでコードを書いて実行できますか?
はい。すべてのTypeScript Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。