mcpField
T
typescript

typescript

github.com/claude-dev-suite開発4650 回インストール1 週間前に更新
リポジトリ

typescript について

型のパターン、設定、コード品質に関する指針をまとめた TypeScript リファレンススキルです。言語の基礎から本番運用や問題解決まで扱います。

主な機能

  1. 01基本型、ジェネリクス、ユーティリティ型
  2. 02型ガードと高度なパターン
  3. 03厳格なコンパイラー設定
  4. 04Lint と本番対応のガイド

活用シーン

  1. 01アプリケーションデータの型選定
  2. 02厳格な TypeScript プロジェクトの設定
  3. 03よくある型エラーの調査

MCP 対応

より包括的な TypeScript ドキュメントを取得するための MCP ドキュメントツールに言及しています。

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/claude-dev-suite/claude-dev-suite --skill typescript

インストール後、Claude Code で/typescriptを入力して読み込まれたか確認します。

同梱ファイルquick-ref/generics.mdquick-ref/utility-types.md

詳細

TypeScript のコア知識

詳細な知識:包括的なドキュメントを参照するには、technology: typescript を指定して mcp__documentation__fetch_docs を使用してください。

基本型

// Primitives
const str: string = 'hello';
const num: number = 42;
const bool: boolean = true;
const arr: number[] = [1, 2, 3];
const tuple: [string, number] = ['hello', 42];

// Objects
interface User {
  id: number;
  name: string;
  email?: string;  // Optional
  readonly createdAt: Date;
}

type Status = 'active' | 'inactive' | 'pending';  // Union

ジェネリクス

// Generic function
function identity<T>(arg: T): T {
  return arg;
}

// Generic interface
interface Repository<T> {
  find(id: string): Promise<T | null>;
  findAll(): Promise<T[]>;
  create(data: Omit<T, 'id'>): Promise<T>;
}

// Generic constraint
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
  return obj[key];
}

ユーティリティ型

Partial<T>      // All properties optional
Required<T>     // All properties required
Pick<T, K>      // Select properties
Omit<T, K>      // Remove properties
Record<K, V>    // Key-value map
Readonly<T>     // All properties readonly
ReturnType<F>   // Function return type
Parameters<F>   // Function parameters
Awaited<T>      // Unwrap Promise

高度なパターン

// Discriminated unions
type Result<T> =
  | { success: true; data: T }
  | { success: false; error: Error };

// Type guards
function isUser(obj: unknown): obj is User {
  return typeof obj === 'object' && obj !== null && 'id' in obj;
}

// Mapped types
type Nullable<T> = { [K in keyof T]: T[K] | null };

// Template literals
type EventName = `on${Capitalize<string>}`;

設定(tsconfig.json)

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "ESNext",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "moduleResolution": "bundler"
  }
}

このスキルを使用しないケース

シナリオ代わりに使用
純粋な JavaScript プロジェクトjavascript スキル
Node.js ランタイムの内部実装nodejs スキル
React 固有の型frontend-react スキル
型アサーションのテストtesting-vitest または testing-jest スキル
スキーマからの型生成api-design-openapi またはフレームワーク固有のスキル

アンチパターン

アンチパターン問題点正しいアプローチ
あらゆる場所で any を使用する型安全性が損なわれますunknown または適切な型を使用する
as による型アサーション実行時エラーが発生する可能性があります型ガードまたは適切な型付けを使用する
大きなユニオン型保守が困難になります判別可能なユニオンまたはブランド型を使用する
interface と type を混在させるコードベースに一貫性がなくなりますどちらかの規約を選ぶ
strictNullChecks を無視するnull/undefined に関する問題が隠れますstrict モードを有効にする
範囲を制限しないインデックスシグネチャ安全でないアクセスにつながります検証付きの Record または Map を使用する
ジェネリクスを深くネストする型が読みにくくなります中間型を切り出す

よくある問題の解決方法

問題原因解決策
"Type 'X' is not assignable to type 'Y'"型の不一致型定義を確認し、型ガードを使用する
"Property 'x' does not exist on type"型がない、または正しくないプロパティを追加するか、インターフェースを修正する
"Cannot find module"型またはパスがない@types をインストールするか、パスを設定する
"Object is possibly 'null'"strictNullChecks が有効オプショナルチェーンまたは null チェックを使用する
"Type instantiation is excessively deep"複雑なジェネリックの再帰型を単純化するか、型の範囲を制限する
"Index signature is missing"動的キーへのアクセスRecord を使用するか、インデックスシグネチャを追加する
ビルドに時間がかかりすぎるファイル数が多く、インクリメンタルビルドが無効インクリメンタルビルドを有効にし、プロジェクト参照を使用する

静的解析とリンティング

公式ルールのリファレンス
ツールルール数ドキュメント
ESLint200+https://eslint.org/docs/latest/rules/
TypeScript-ESLint100+https://typescript-eslint.io/rules/
Biome200+https://biomejs.dev/linter/rules/
SonarJS422https://rules.sonarsource.com/javascript/
有効にする主要ルール
// eslint.config.js (ESLint 9+)
export default [
  {
    rules: {
      // Prevent bugs
      'no-unused-vars': 'error',
      '@typescript-eslint/no-floating-promises': 'error',
      '@typescript-eslint/no-misused-promises': 'error',

      // Code quality
      '@typescript-eslint/explicit-function-return-type': 'warn',
      '@typescript-eslint/no-explicit-any': 'warn',
      'complexity': ['warn', 10],
      'max-depth': ['warn', 4],
    }
  }
];
推奨設定
ツール設定コマンド
ESLint@eslint/js recommendednpm init @eslint/config
TypeScript-ESLintstrict-type-checkedts-eslint のドキュメントを参照
Biomeデフォルトnpx @biomejs/biome init

本番環境への準備

厳格な設定
// tsconfig.json
{
  "compilerOptions": {
    "target": "ES2022",
    "module": "ESNext",
    "moduleResolution": "bundler",
    "strict": true,
    "noUncheckedIndexedAccess": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "exactOptionalPropertyTypes": true,
    "forceConsistentCasingInFileNames": true,
    "verbatimModuleSyntax": true,
    "skipLibCheck": true,
    "declaration": true,
    "declarationMap": true,
    "sourceMap": true
  },
  "include": ["src"],
  "exclude": ["node_modules", "dist"]
}
エラー処理
// Type-safe error handling
class AppError extends Error {
  constructor(
    message: string,
    public readonly code: string,
    public readonly statusCode: number = 500
  ) {
    super(message);
    this.name = 'AppError';
  }
}

// Result type pattern
type Result<T, E = Error> =
  | { success: true; data: T }
  | { success: false; error: E };

async function safeAsync<T>(
  promise: Promise<T>
): Promise<Result<T>> {
  try {
    const data = await promise;
    return { success: true, data };
  } catch (error) {
    return { success: false, error: error as Error };
  }
}

// Usage
const result = await safeAsync(fetchUser(id));
if (result.success) {
  console.log(result.data);
} else {
  console.error(result.error.message);
}
型安全性のパターン
// Branded types for type safety
type UserId = string & { readonly brand: unique symbol };
type OrderId = string & { readonly brand: unique symbol };

function createUserId(id: string): UserId {
  return id as UserId;
}

// Exhaustive checking
function assertNever(x: never): never {
  throw new Error(`Unexpected value: ${x}`);
}

type Status = 'active' | 'inactive' | 'pending';

function handleStatus(status: Status): string {
  switch (status) {
    case 'active': return 'Active';
    case 'inactive': return 'Inactive';
    case 'pending': return 'Pending';
    default: return assertNever(status);
  }
}

// Zod for runtime validation
import { z } from 'zod';

const UserSchema = z.object({
  id: z.string().uuid(),
  email: z.string().email(),
  name: z.string().min(2),
});

type User = z.infer<typeof UserSchema>;

function parseUser(data: unknown): User {
  return UserSchema.parse(data);
}
テスト
// Type testing with expectTypeOf
import { expectTypeOf, describe, it } from 'vitest';

describe('types', () => {
  it('User has correct shape', () => {
    expectTypeOf<User>().toMatchTypeOf<{
      id: string;
      email: string;
      name: string;
    }>();
  });

  it('createUser returns User', () => {
    expectTypeOf(createUser).returns.toEqualTypeOf<User>();
  });
});

// Unit testing with proper types
import { describe, it, expect, vi } from 'vitest';

describe('UserService', () => {
  it('fetches user by id', async () => {
    const mockUser: User = {
      id: '123',
      email: '[email protected]',
      name: 'Test',
    };

    const repository = {
      findById: vi.fn().mockResolvedValue(mockUser),
    };

    const service = new UserService(repository);
    const result = await service.getUser('123');

    expect(result).toEqual(mockUser);
    expect(repository.findById).toHaveBeenCalledWith('123');
  });
});
パフォーマンス
// Lazy initialization
class ExpensiveService {
  private static instance: ExpensiveService | null = null;

  static getInstance(): ExpensiveService {
    if (!this.instance) {
      this.instance = new ExpensiveService();
    }
    return this.instance;
  }
}

// Memoization with proper types
function memoize<Args extends unknown[], Result>(
  fn: (...args: Args) => Result
): (...args: Args) => Result {
  const cache = new Map<string, Result>();

  return (...args: Args): Result => {
    const key = JSON.stringify(args);
    if (cache.has(key)) {
      return cache.get(key)!;
    }
    const result = fn(...args);
    cache.set(key, result);
    return result;
  };
}
監視指標
指標目標
型カバレッジ> 95%
any の使用0 件
ビルド時間< 30s
型エラー0
チェックリスト
  • strict: true を有効化
  • noUncheckedIndexedAccess を有効化
  • 明示的な any の使用なし
  • ID にブランド型を使用
  • エラー処理に Result 型を使用
  • Zod によるランタイム検証
  • expectTypeOf による型テスト
  • 宣言ファイルを生成
  • ソースマップを有効化
  • typescript-eslint を使用した ESLint

リファレンスドキュメント

詳細な知識:包括的なドキュメントを参照するには、technology: typescript を指定して mcp__documentation__fetch_docs を使用してください。

コメント