typescript-best-practices について
一貫性と型安全性を重視する TypeScript 開発者向けの開発スキルです。厳格な設定、実行時検証、エラー処理、インポート規約を扱い、詳細なトピック別リファレンスも備えています。
主な機能
- 01厳格な TypeScript 設定
- 02公開 API の明示的な型
- 03判別共用体と Result 型
- 04実行時の型ガードとアサーション
- 05インポートとエクスポートの規約
- 06トピック別リファレンス
活用シーン
- 01tsconfig.json の厳格な設定
- 02接続状態や処理結果のモデル化
- 03実行時の未知データの検証
- 04インポート整理と循環依存の回避
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ ghosttypes/ ff-5mp-api-ts --skill typescript-best-practicesインストール後、Claude Code で/typescript-best-practicesを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/error-handling.mdgenerics.mdimport-export.mdinterfaces-types.mdtsconfig.mdtype-guards-assertions.mdunions-discriminated.mdutility-types.md詳細
TypeScript のベストプラクティス
クイックスタート
常に strict モードを有効にし、公開 API には明示的な型を使用してください。型のみのインポート(import type)と名前付きエクスポートをデフォルトエクスポートより優先してください。状態管理には判別可能なユニオンを、実行時の検証には型ガードを使用してください。
型安全性の基本
Strict モードの設定
tsconfig.json ですべての strict フラグを有効にします:
{
"strict": true,
"noImplicitAny": true,
"noImplicitReturns": true,
"strictNullChecks": true,
"strictFunctionTypes": true
}
Null の安全性
// Explicit null handling
export function findById<T>(items: Map<string, T>, id: string): T | null {
return items.get(id) ?? null;
}
// Optional chaining and nullish coalescing
export function getName(item?: Item): string {
return item?.name ?? 'Unknown';
}
明示的な戻り値の型
公開 API には明示的な戻り値の型を使用します:
// Good
export function validateConfig(data: unknown): ValidatedConfig | null {
const result = ConfigSchema.safeParse(data);
return result.success ? result.data : null;
}
// Bad - implicit return type
export function validateConfig(data) {
return data;
}
基本パターン
状態管理のための判別可能なユニオン
export type ConnectionState =
| { status: 'disconnected' }
| { status: 'connecting'; progress: number }
| { status: 'connected'; connectionId: string }
| { status: 'error'; message: string };
// TypeScript knows which properties are available in each branch
エラー処理のための Result 型
export type Result<T, E = Error> =
| { success: true; data: T }
| { success: false; error: E };
const result = await connectToService(options);
if (result.success) {
console.log('Connected:', result.data.id);
} else {
console.error('Failed:', result.error.message);
}
読み取り専用プロパティ
変更できないデータには readonly を使用します:
export interface Config {
readonly enableFeature: boolean;
readonly port: number;
}
型ガードとアサーション
// Type guard
export function isUserData(data: unknown): data is UserData {
return typeof data === 'object' && data !== null && 'name' in data;
}
// Assertion function
export function assertIsDefined<T>(value: T): asserts value is NonNullable<T> {
if (value === undefined || value === null) throw new Error('Value is undefined or null');
}
インポート/エクスポートの規約
// Type-only imports (preferred)
import type { Config } from '../types/config';
// Named exports (avoid default exports)
export class DataService {}
export const getService = () => DataService.getInstance();
// Grouped imports
import { External } from 'external'; // External deps
import { internalUtil } from './utils'; // Internal utils
import type { MyType } from './types'; // Types
参照ファイルを使うタイミング
| 参照ファイル | 読み込むタイミング |
|---|---|
tsconfig.md | TypeScript の設定を行うとき |
interfaces-types.md | インターフェースやジェネリック型の定義、外部型の拡張を行うとき |
unions-discriminated.md | 判別可能なユニオン、Result 型、網羅性チェックを扱うとき |
type-guards-assertions.md | 実行時の検証、ブランド型、アサーション関数を扱うとき |
utility-types.md | 組み込みユーティリティ、const アサーション、テンプレートリテラル型を使うとき |
error-handling.md | 構造化エラー、エラーファクトリー、再試行ロジックを実装するとき |
generics.md | ジェネリックサービス、リポジトリ、ファクトリー、イベントエミッターを構築するとき |
import-export.md | インポート/エクスポートを整理し、循環依存を避けるとき |
避けるべき一般的なアンチパターン
anyの使用 - 代わりに型ガードとともにunknownを使用します- デフォルトエクスポート - リファクタリングやツリーシェイキングが難しくなります
- 公開 API の暗黙的な戻り値の型
- 変更できないデータに対する非 readonly インターフェース
- ネストされたオプショナル(
{ a?: { b?: string } })- 代わりに判別可能なユニオンを使用します
コメント
Markdown 対応