TypeScript開発のベストプラクティス
· 約2分
TypeScriptを使った開発において、品質の高いコードを書くためのベストプラクティスを紹介します。
型定義のベストプラクティス
interfaceとtypeの使い分け
// オブジェクトの構造にはinterfaceを使用
interface User {
id: number;
name: string;
email: string;
}
// ユニオン型や計算された型にはtypeを使用
type Status = 'loading' | 'success' | 'error';
type UserKeys = keyof User;
厳密な型チェック
// tsconfig.jsonで厳密モードを有効にする
{
"compilerOptions": {
"strict": true,
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true
}
}
ジェネリクスの活用
型安全性を保ちながら再利用可能なコードを書くためにジェネリクスを活用しましょう。
function fetchData<T>(url: string): Promise<T> {
return fetch(url).then(response => response.json());
}
// 使用例
interface Post {
id: number;
title: string;
content: string;
}
const posts = await fetchData<Post[]>('/api/posts');
型ガードの実装
ランタイムでの型安全性を確保するために型ガードを使用します。
function isString(value: unknown): value is string {
return typeof value === 'string';
}
function isUser(obj: unknown): obj is User {
return (
typeof obj === 'object' &&
obj !== null &&
'id' in obj &&
'name' in obj &&
'email' in obj
);
}
// 使用例
function processUserData(data: unknown) {
if (isUser(data)) {
// この時点でdataはUser型として扱われる
console.log(data.name);
}
}
ユーティリティ型の活用
TypeScriptの組み込みユーティリティ型を活用しましょう。
// Partial: すべてのプロパティを任意にする
function updateUser(id: number, updates: Partial<User>) {
// 実装
}
// Pick: 特定のプロパティのみを選択
type UserSummary = Pick<User, 'id' | 'name'>;
// Omit: 特定のプロパティを除外
type CreateUser = Omit<User, 'id'>;
エラーハンドリング
型安全なエラーハンドリングのパターンです。
type Result<T, E = Error> = {
success: true;
data: T;
} | {
success: false;
error: E;
};
async function safeApiCall<T>(
apiCall: () => Promise<T>
): Promise<Result<T>> {
try {
const data = await apiCall();
return { success: true, data };
} catch (error) {
return {
success: false,
error: error instanceof Error ? error : new Error('Unknown error')
};
}
}
まとめ
これらのベストプラクティスを適用することで、保守性と可読性の高いTypeScriptコードを書くことができます。型システムを最大限活用して、バグの少ないアプリケーションを開発しましょう。
コメント
コメントはまだありません