型レベルDSLのエラーメッセージ
DSLユーザーに役立つコンパイルエラーを提示します。
「型レベルDSLのエラーメッセージ」はCoddyKit上の無料TypeScript Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはTypeScript Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 TypeScript Academyコースには全4レッスンが含まれています。
型レベル DSL で役立つエラー
型レベル DSL で最も難しいのは、失敗を読みやすくすることです。never や「代入できない」というだけのエラーでは、ユーザーは混乱します。ブランド付きエラー型と、メッセージを組み込んだ never を使って、説明的なエラーを表示します。
never の問題点
検証が never に解決されて失敗すると、コンパイラーは「Argument of type X is not assignable to never」と表示しますが、これではユーザーに失敗の理由が伝わりません。もっと改善できます。
ブランド付きエラー型
単なる never の代わりに、型の中に人間が読めるメッセージ文字列を持つ、固有の形をしたエラー型を返します。
type TypeError<Msg extends string> = {
readonly __error: Msg;
};
type E = TypeError<"Column 'foo' does not exist">;検証からエラーを返す
バリデーターは、有効な値の型か、問題の内容を説明するブランド付きエラーのどちらかを返します。「ドットがある」チェックはテンプレートリテラルパターンです(実際のコードではバッククォートを使います)。ここでは HasDot と表記します。
// HasDot<S> is the backtick pattern: any text, ".", any text.
type Validate<S extends string> =
S extends HasDot
? S
: TypeError<"Path must contain a dot, e.g. user.name">;エラーを表面化させる
エラーブランドに代入できない値を渡すとメッセージが表示されるように、パラメーターを制約します。エラー型がコンパイラーの出力に直接現れます。
declare function path<S extends string>(
p: Validate<S> extends TypeError<infer M> ? TypeError<M> : S
): void;
path("oops");
// Error message includes: __error: "Path must contain a dot..."複数のエラーを区別する
失敗ごとに異なるメッセージを返すため、ユーザーは一律の拒否ではなく、具体的な対処方法を得られます。HasDot はここでも「ドットを含む」ことを表すバッククォートのテンプレートリテラルパターンです。
type Check<S extends string> =
S extends "" ? TypeError<"Path cannot be empty">
: S extends HasDot ? S
: TypeError<"Missing dot separator">;ひと工夫した never
別の方法として、値の位置にリテラルメッセージを組み合わせると、ホバー時にメッセージを表示できます。問題のある型とラベル付きオブジェクトを交差させます。
type Invalid<M extends string> = { error: M } & never;
// using never keeps it unassignable while the label hints the cause流暢な DSL のエラー
チェーンでつなぐ DSL では、次に選べないステップが有効なステージではなく、エラーであることを示すブランド付き型を返すようにします。これにより、間違いの場所でエディターにメッセージを表示できます。
interface Stage {
// calling done() before where() yields a labeled error
done(): TypeError<"Call .where() before .done()">;
}メッセージを短く保つ
長いメッセージ型はコンパイラーの出力を膨らませ、ツールの動作を遅くします。簡潔で、すぐ行動に移せる表現を選んでください。低コストで済む場合は問題のあるトークンを含めますが、大きな文字列の埋め込みは避けてください。
エラーをテストする
既知の不正な入力に対してエラーブランドが現れることを検証する型レベルテストを書き、リファクタリングによって開発者体験が気付かないうちに低下しないようにします。
type Expect<T extends true> = T;
type _t = Expect<Validate<"oops"> extends TypeError<any> ? true : false>;重要な理由
DSL の品質はエラーの品質によって決まります。ブランド付きエラー型を使うと、分かりにくい never の失敗を自己説明的なメッセージに変えられ、型レベル API の使いやすさが大きく向上します。
理解度チェック
型レベルのエラーメッセージについて理解できているか確認してください。
まとめ
型レベル DSL を使いやすくするには、単独の never を、読みやすいメッセージを埋め込んだブランド付きエラー型に置き換えます。バリデーターは有効な型か、具体的なエラーブランドのどちらかを返し、パラメーターを制約することでコンパイラーの出力にメッセージを表示します。メッセージは短く保ち、テストしてください。
よくある質問
「型レベルDSLのエラーメッセージ」レッスンは無料ですか?
はい。「型レベルDSLのエラーメッセージ」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、TypeScript Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 TypeScript Academyコースには全4レッスンが含まれています。
「型レベルDSLのエラーメッセージ」で何を学びますか?
DSLユーザーに役立つコンパイルエラーを提示します。 ブラウザで直接実行するハンズオンコードでTypeScript Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
TypeScript Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのTypeScript Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。
「型レベルDSLのエラーメッセージ」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このTypeScript Academyレッスンでコードを書いて実行できますか?
はい。すべてのTypeScript Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- 型レベルDSLとは
- Fluent Query DSLの設計
- コンパイル時の入力バリデーション
- 型レベルDSLのエラーメッセージ