mastering-typescript
型安全なパターン・最新ツールチェーン・フレームワーク連携を網羅した、エンタープライズグレードの TypeScript 開発をマスターするためのスキルです。TypeScript 5.9+ の型システム基礎(ジェネリクス、マップ型、条件型、satisfies 演算子)からエンタープライズパターン(エラーハンドリング、Zod によるバリデーション)、React・NestJS・LangChain.js との統合まで包括的なガイダンスを提供します。型安全なアプリケーション構築、JavaScript コードベースの移行、Vite 7・pnpm・ESLint・Vitest などのモダンなツールチェーン設定、高度な型パターンの実装、あるいは Java/Python との比較検討を行う際に活用してください。
description の原文を見る
| Master enterprise-grade TypeScript development with type-safe patterns, modern tooling, and framework integration. This skill provides comprehensive guidance for TypeScript 5.9+, covering type system fundamentals (generics, mapped types, conditional types, satisfies operator), enterprise patterns (error handling, validation with Zod), React integration for type-safe frontends, NestJS for scalable APIs, and LangChain.js for AI applications. Use when building type-safe applications, migrating JavaScript codebases, configuring modern toolchains (Vite 7, pnpm, ESLint, Vitest), implementing advanced type patterns, or comparing TypeScript with Java/Python approaches.
SKILL.md 本文
モダン TypeScript のマスタリング
TypeScript 5.9+ を使ったエンタープライズグレードの型安全なアプリケーションを構築します。
互換性: TypeScript 5.9+、Node.js 22 LTS、Vite 7、NestJS 11、React 19
クイックスタート
# ESM 対応 TypeScript プロジェクトを初期化
pnpm create vite@latest my-app --template vanilla-ts
cd my-app && pnpm install
# 厳密な TypeScript を設定
cat > tsconfig.json << 'EOF'
{
"compilerOptions": {
"target": "ES2024",
"module": "ESNext",
"moduleResolution": "bundler",
"strict": true,
"noUncheckedIndexedAccess": true,
"exactOptionalPropertyTypes": true,
"esModuleInterop": true,
"skipLibCheck": true
}
}
EOF
このスキルを使う時
以下の場合に使用します:
- 型安全な React、NestJS、または Node.js アプリケーションを構築する
- JavaScript コードベースを TypeScript にマイグレーションする
- 高度な型パターン(ジェネリクス、マップ型、条件付き型)を実装する
- モダン TypeScript ツールチェーン(Vite、pnpm、ESLint)を設定する
- Zod 検証で型安全な API コントラクトを設計する
- TypeScript のアプローチを Java や Python と比較する
プロジェクト設定チェックリスト
任意の TypeScript プロジェクトを開始する前に:
- [ ] パッケージ管理に pnpm を使用(高速、ディスク効率的)
- [ ] ESM ファースト設定(package.json に type: "module")
- [ ] tsconfig.json で厳密モードを有効化
- [ ] @typescript-eslint で ESLint をセットアップ
- [ ] 一貫したフォーマットのために Prettier を追加
- [ ] テストのために Vitest を設定
型システム クイックリファレンス
プリミティブ型
const name: string = "Alice";
const age: number = 30;
const active: boolean = true;
const id: bigint = 9007199254740991n;
const key: symbol = Symbol("unique");
ユニオン型とインターセクション型
// ユニオン: 値は複数の型のいずれかになります
type Status = "pending" | "approved" | "rejected";
// インターセクション: 値はすべての型を満たす必要があります
type Employee = Person & { employeeId: string };
// 判別可能なユニオンで型安全なハンドリング
type Result<T> =
| { success: true; data: T }
| { success: false; error: string };
function handleResult<T>(result: Result<T>): T | null {
if (result.success) {
return result.data; // TypeScript はここで data が存在することを知っています
}
console.error(result.error);
return null;
}
型ガード
// typeof ガード
function process(value: string | number): string {
if (typeof value === "string") {
return value.toUpperCase();
}
return value.toFixed(2);
}
// カスタム型ガード
interface User { type: "user"; name: string }
interface Admin { type: "admin"; permissions: string[] }
function isAdmin(person: User | Admin): person is Admin {
return person.type === "admin";
}
satisfies オペレーター(TS 5.0+)
型の適合性を検証しながら推論を保持します:
// 問題: 型アサーションは具体的な型情報を失う
const colors1 = {
red: "#ff0000",
green: "#00ff00"
} as Record<string, string>;
colors1.red.toUpperCase(); // OK だが、red は undefined の可能性
// 解決: satisfies はリテラル型を保持
const colors2 = {
red: "#ff0000",
green: "#00ff00"
} satisfies Record<string, string>;
colors2.red.toUpperCase(); // OK で、TypeScript は red が存在することを知っている
ジェネリクスパターン
基本的なジェネリック関数
function first<T>(items: T[]): T | undefined {
return items[0];
}
const num = first([1, 2, 3]); // number | undefined
const str = first(["a", "b"]); // string | undefined
制約付きジェネリクス
interface HasLength {
length: number;
}
function logLength<T extends HasLength>(item: T): T {
console.log(item.length);
return item;
}
logLength("hello"); // OK: string は length を持つ
logLength([1, 2, 3]); // OK: array は length を持つ
logLength(42); // エラー: number は length を持たない
ジェネリック API レスポンスラッパー
interface ApiResponse<T> {
data: T;
status: number;
timestamp: Date;
}
async function fetchUser(id: string): Promise<ApiResponse<User>> {
const response = await fetch(`/api/users/${id}`);
const data = await response.json();
return {
data,
status: response.status,
timestamp: new Date()
};
}
ユーティリティ型リファレンス
| 型 | 目的 | 例 |
|---|---|---|
Partial<T> | すべてのプロパティをオプション化 | Partial<User> |
Required<T> | すべてのプロパティを必須化 | Required<Config> |
Pick<T, K> | 特定のプロパティを選択 | Pick<User, "id" | "name"> |
Omit<T, K> | 特定のプロパティを除外 | Omit<User, "password"> |
Record<K, V> | 型付きキー/値を持つオブジェクト | Record<string, number> |
ReturnType<F> | 関数の戻り値型を抽出 | ReturnType<typeof fn> |
Parameters<F> | 関数のパラメータを抽出 | Parameters<typeof fn> |
Awaited<T> | Promise 型をアンラップ | Awaited<Promise<User>> |
条件付き型
// 基本的な条件付き型
type IsString<T> = T extends string ? true : false;
// 配列要素型を抽出
type ArrayElement<T> = T extends (infer E)[] ? E : never;
type Numbers = ArrayElement<number[]>; // number
type Strings = ArrayElement<string[]>; // string
// 実践的: Promise の結果型を抽出
type UnwrapPromise<T> = T extends Promise<infer R> ? R : T;
マップ型
// すべてのプロパティを readonly に
type Immutable<T> = {
readonly [K in keyof T]: T[K];
};
// すべてのプロパティをヌル許容に
type Nullable<T> = {
[K in keyof T]: T[K] | null;
};
// 各プロパティのゲッター関数を作成
type Getters<T> = {
[K in keyof T as `get${Capitalize<string & K>}`]: () => T[K];
};
interface Person { name: string; age: number }
type PersonGetters = Getters<Person>;
// { getName: () => string; getAge: () => number }
フレームワーク統合
React with TypeScript
// 型付き関数型コンポーネント
interface ButtonProps {
label: string;
onClick: () => void;
variant?: "primary" | "secondary";
}
const Button: React.FC<ButtonProps> = ({ label, onClick, variant = "primary" }) => (
<button className={variant} onClick={onClick}>
{label}
</button>
);
// 型付きフック
const [count, setCount] = useState<number>(0);
const userRef = useRef<HTMLInputElement>(null);
NestJS with TypeScript
// class-validator を使用した型安全な DTO
import { IsString, IsEmail, MinLength } from 'class-validator';
class CreateUserDto {
@IsString()
@MinLength(2)
name: string;
@IsEmail()
email: string;
}
// または Zod(モダンなアプローチ)
import { z } from 'zod';
const CreateUserSchema = z.object({
name: z.string().min(2),
email: z.string().email()
});
type CreateUserDto = z.infer<typeof CreateUserSchema>;
詳細なパターンについては react-integration.md と nestjs-integration.md を参照してください。
Zod による検証
import { z } from 'zod';
// スキーマを定義
const UserSchema = z.object({
id: z.string().uuid(),
name: z.string().min(1).max(100),
email: z.string().email(),
role: z.enum(["user", "admin", "moderator"]),
createdAt: z.coerce.date()
});
// スキーマから TypeScript 型を推論
type User = z.infer<typeof UserSchema>;
// ランタイムで検証
function parseUser(data: unknown): User {
return UserSchema.parse(data); // 無効な場合は ZodError をスロー
}
// 安全な解析(結果オブジェクトを返す)
const result = UserSchema.safeParse(data);
if (result.success) {
console.log(result.data); // User として型付け
} else {
console.error(result.error.issues);
}
モダンツールチェーン(2025)
| ツール | バージョン | 目的 |
|---|---|---|
| TypeScript | 5.9+ | 型チェックとコンパイル |
| Node.js | 22 LTS | ランタイム環境 |
| Vite | 7.x | ビルドツールと開発サーバー |
| pnpm | 9.x | パッケージマネージャー |
| ESLint | 9.x | フラット設定によるリント |
| Vitest | 3.x | テストフレームワーク |
| Prettier | 3.x | コードフォーマッター |
ESLint フラット設定(ESLint 9+)
// eslint.config.js
import eslint from '@eslint/js';
import tseslint from 'typescript-eslint';
export default tseslint.config(
eslint.configs.recommended,
...tseslint.configs.strictTypeChecked,
{
languageOptions: {
parserOptions: {
projectService: true,
tsconfigRootDir: import.meta.dirname,
},
},
}
);
マイグレーション戦略
段階的マイグレーション
- tsconfig.json に
allowJs: trueとcheckJs: falseを追加 - ファイルを
.jsから.tsに 1 つずつ名前変更 - 型アノテーションを段階的に追加
- より厳密なオプションを段階的に有効化
段階的な型付けのための JSDoc
// フルマイグレーションの前に、JSDoc を使用
/**
* @param {string} name
* @param {number} age
* @returns {User}
*/
function createUser(name, age) {
return { name, age };
}
包括的なマイグレーションガイドについては enterprise-patterns.md を参照してください。
よくある間違い
| 間違い | 問題 | 修正 |
|---|---|---|
any を頻繁に使用 | 型安全性を損なう | unknown を使用して絞り込む |
| 厳密モードを無視 | null/undefined のバグを見落とす | すべての厳密オプションを有効化 |
型アサーション(as)を使用 | 型エラーを隠す可能性 | satisfies またはガードを使用 |
| シンプルなユニオンに enum を使用 | ランタイムコードが生成される | リテラルユニオンを使用 |
| API データを検証しない | ランタイムの型不一致 | 境界で Zod を使用 |
言語間の比較
| 機能 | TypeScript | Java | Python |
|---|---|---|---|
| 型システム | 構造的 | 名義的 | 段階的(ダックタイピング) |
| Null 許容性 | 明示的(T | null) | @Nullable アノテーション | typing による省略可能 |
| ジェネリクス | 型レベル、消去される | 型レベル、消去される | typing による実行時 |
| インターフェース | 構造的マッチング | 実装が必要 | Protocol(3.8+) |
| Enum | 避ける(ユニオンを使用) | ファーストクラス | Enum クラス |
リファレンスファイル
type-system.md— 完全な型システムガイドgenerics.md— 高度なジェネリクスパターンenterprise-patterns.md— エラーハンドリング、検証、アーキテクチャreact-integration.md— React + TypeScript パターンnestjs-integration.md— NestJS API 開発toolchain.md— モダンビルドツールの設定
アセット
tsconfig-template.json— 厳密なエンタープライズ設定eslint-template.js— ESLint 9 フラット設定
スクリプト
validate-setup.sh— TypeScript 環境を検証
ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ
詳細情報
- 作者
- spillwavesolutions
- ライセンス
- MIT
- 最終更新
- 不明
Source: https://github.com/spillwavesolutions/mastering-typescript-skill / ライセンス: MIT
関連スキル
agent-browser
AI エージェント向けのブラウザ自動化 CLI です。ウェブサイトとの対話が必要な場合に使用します。ページ遷移、フォーム入力、ボタンクリック、スクリーンショット取得、データ抽出、ウェブアプリのテスト、ブラウザ操作の自動化など、あらゆるブラウザタスクに対応できます。「ウェブサイトを開く」「フォームに記入する」「ボタンをクリックする」「スクリーンショットを取得する」「ページからデータを抽出する」「このウェブアプリをテストする」「サイトにログインする」「ブラウザ操作を自動化する」といった要求や、プログラマティックなウェブ操作が必要なタスクで起動します。
anyskill
AnySkill — あなたのプライベート・スキルクラウド。GitHubを基盤としたリポジトリからエージェントスキルを管理、同期、動的にロードできます。自然言語でクラウドスキルを検索し、オンデマンドでプロンプトを自動ロード、カスタムスキルのアップロードと共有、スキルバンドルの一括インストールが可能です。OpenClaw、Antigravity、Claude Code、Cursorに対応しています。
engram
AIエージェント向けの永続的なメモリシステムです。バグ修正、意思決定、発見、設定変更の後はmem_saveを使用してください。ユーザーが「覚えている」「記憶している」と言及した場合、または以前のセッションと重複する作業を開始する際はmem_searchを使用します。セッション終了前にmem_session_summaryを使用して、コンテキストを保持してください。
skyvern
AI駆動のブラウザ自動化により、任意のウェブサイトを自動化できます。フォーム入力、データ抽出、ファイルダウンロード、ログイン、複数ステップのワークフロー実行など、ユーザーがウェブサイトと連携する必要があるときに使用します。Skyvernは、LLMとコンピュータビジョンを活用して、未知のサイトも自動操作可能です。Python SDK、TypeScript SDK、REST API、MCPサーバー、またはCLIを通じて統合できます。
pinchbench
PinchBenchベンチマークを実行して、OpenClawエージェントの実世界タスクにおけるパフォーマンスを評価できます。モデルの機能テスト、モデル間の比較、ベンチマーク結果のリーダーボード提出、またはOpenClawのセットアップがカレンダー、メール、リサーチ、コーディング、複数ステップのワークフローにどの程度対応しているかを確認する際に使用します。
openui
OpenUIとOpenUI Langを使用してジェネレーティブUIアプリを構築できます。これらはLLM生成インターフェースのためのトークン効率的なオープン標準です。OpenUI、@openuidev、ジェネレーティブUI、LLMからのストリーミングUI、AI向けコンポーネントライブラリ、またはjson-render/A2UIの置き換えについて述べる際に使用します。スキャフォルディング、defineComponent、システムプロンプト、Renderer、およびOpenUI Lang出力のデバッグに対応しています。