type-display-attention について
複雑な型を IDE のツールチップやエラーメッセージで読みやすく保ちたい TypeScript 開発者向けのスキルです。型エイリアスや同一マップ型による表示制御を扱います。
主な機能
- 01IDE での型の可読性向上
- 02複雑な型のエイリアス化
- 03同一マップ型の活用
- 04ツールチップとエラーの確認
活用シーン
- 01深くネストした型表示の整理
- 02ジェネリックな公開 API の可読性向上
- 03分かりにくい型エラーの調査
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ marius-townhouse/ effective-typescript-skills --skill type-display-attentionインストール後、Claude Code で/type-display-attentionを入力して読み込まれたか確認します。
詳細
型の表示方法に注意する
概要
記述する型は、コンパイラーだけでなく、IDE でコードを読む開発者にも向けたものです。複雑な型は扱いにくい展開表示になり、意味をわかりにくくして開発者体験を損なうことがあります。型の表示方法を制御する方法を理解すれば、正確で読みやすい型を作成できます。
型の表示は、デバッグ、API の使いやすさ、そして開発者の全体的な生産性に関わります。正しく動作しても表示が悪い型は、作業の妨げになります。
このスキルを使う場面
- ホバー時のツールチップで複雑な型が見づらく表示される
- 名前付きの型ではなく、展開された型が表示される
- わかりにくい型エラーをデバッグする
- ジェネリック型を使った公開 API を構築する
- 型が深くネストしたり、再帰的になったりする
絶対に守るべきルール
型エイリアスと恒等写像型を使って、型の表示方法を制御してください。IDE のツールチップやエラーメッセージで、型が読みやすく表示されるようにします。
問題の検出
次のような表示上の問題に注意してください。
// UGLY DISPLAY - Users see this expansion:
// { [K in keyof T as ToCamel<K & string>]: T[K] }
// Instead of a clean name
// CONFUSING ERROR - Type displays as:
// { a: { b: { c: { d: string } } } }
// Instead of: DeepNested<string>
恒等写像型のテクニック
TypeScript に型エイリアスを維持させます。
// Without trick - displays as expansion
type ObjectToCamel<T> = {
[K in keyof T as ToCamel<K & string>]: T[K]
};
const result = objectToCamel({ foo_bar: 1 });
// Hover shows: { [K in keyof T as ToCamel<...
// With identity mapped type - displays as name
type ObjectToCamel<T> = {
[K in keyof T as ToCamel<K & string>]: T[K]
} extends infer O
? { [K in keyof O]: O[K] }
: never;
const result = objectToCamel({ foo_bar: 1 });
// Hover shows: ObjectToCamel<{ foo_bar: number }>
わかりやすい型エイリアスの作成
// BAD: Complex inline type
function processData(
input: { [K in keyof User as `set${Capitalize<K & string>}`]: User[K] }
): void;
// GOOD: Named type alias
type SetterMethods<T> = {
[K in keyof T as `set${Capitalize<K & string>}`]: T[K]
};
function processData(input: SetterMethods<User>): void;
// Displays as: SetterMethods<User>
複雑な戻り値の型を簡潔にする
// Complex generic return type
type QueryResult<T> = T extends { data: infer D }
? D extends Array<infer Item>
? PaginatedResult<Item>
: SingleResult<D>
: ErrorResult;
// Simplify display with intermediate type
type QueryResult<T> = T extends { data: infer D }
? QueryResultHelper<D>
: ErrorResult;
type QueryResultHelper<D> = D extends Array<infer Item>
? PaginatedResult<Item>
: SingleResult<D>;
実装の詳細を隠す
// Internal complex type
type InternalTransform<T> = /* complex 10-line type */;
// Public clean type
type PublicType<T> = InternalTransform<T> extends infer R
? { [K in keyof R]: R[K] }
: never;
// Users see: PublicType<T>
// Not the messy InternalTransform expansion
ユニオン型で型名を維持する
// Each branch keeps its name
type Result<T> =
| { type: 'success'; data: T }
| { type: 'error'; error: Error }
| { type: 'loading' };
// Displays cleanly as:
// Result<User> =
// | { type: 'success'; data: User }
// | { type: 'error'; error: Error }
// | { type: 'loading' }
型の表示をテストする
実際に型がどのように表示されるか確認します。
// Create test cases to see how types display
type TestCase1 = YourComplexType<{ a: string }>;
// Hover over TestCase1 to see display
type TestCase2 = YourComplexType<{ nested: { deep: number } }>;
// Check nested case
// Check error messages
const x: TestCase1 = {} as any;
// Trigger an error to see how type appears in message
IDE ごとの考慮事項
IDE によって型の表示方法は異なります。
// VS Code: Hover to see type
type Example = /* your type */;
// Check in:
// - Hover tooltips
// - IntelliSense autocomplete
// - Error message panels
// - Quick fix suggestions
問題への対処手順
型の表示が適切でない場合:
- ホバー時のツールチップを確認する:ユーザーに実際に何が表示されるか確認します
- エイリアスを導入する:複雑な型を名前付きの要素に分割します
- 恒等写像型を使う:型名を維持させます
- エラーメッセージをテストする:エラーにわかりやすい型名が表示されることを確認します
- 簡素化を検討する:型が複雑すぎる可能性があります
注意すべき兆候
| 症状 | 問題 | 解決策 |
|---|---|---|
| 型が展開されて表示される | エイリアスが維持されていない | 恒等写像型 |
| 深くネストした表示 | 階層が多すぎる | 中間の型エイリアス |
| ジェネリック型のノイズ | 型パラメーターが多すぎる | 簡素化するか、デフォルト値を使う |
| エラー内で読みにくい | 条件型が複雑 | 名前付きの結果型 |
よくある言い訳
「ユーザーは展開された型を読めます」
実際には:複雑な展開表示は読みづらいものです。わかりやすい名前なら、意図がすぐに伝わります。
「内部でしか使いません」
実際には:内部型も同僚(そして未来の自分)が読みます。わかりやすい表示は、誰にとっても役立ちます。
「型そのものが複雑なのです」
実際には:わかりやすいインターフェースの背後に複雑さを隠せます。ユーザーが実装の仕組みをすべて見る必要はありません。
クイックリファレンス
| テクニック | 構文 | 使用する場面 |
|---|---|---|
| 型エイリアス | type Name = ... | あらゆる複雑な型 |
| 恒等写像 | extends infer O ? { [K in keyof O]: O[K] } : never | 型名を維持させる |
| 中間型 | 手順ごとに分割する | 複数ステップの変換 |
| ユニオンの分岐 | 名前付きオブジェクト型 | 判別可能なユニオン |
要点
型はユーザーインターフェースです。エイリアスと恒等写像型を使って、型の表示方法を制御してください。ホバー時のツールチップやエラーメッセージで型が読みやすく表示されれば、開発者体験が向上します。
参考資料
- Dan Vanderkam 著『Effective TypeScript』第 2 版
- 項目 56:型の表示方法に注意する