jpskill.com
🛠️ 開発・MCP コミュニティ 🔴 エンジニア向け 👤 エンジニア・AI開発者

🛠️ Typescript Best Practices

typescript-best-practices

TypeScriptやJavaScriptのプログラムファイルを効率的かつ高品質に作成

⏱ ライブラリ調査+組込 半日 → 1時間

📺 まず動画で見る(YouTube)

▶ 【衝撃】最強のAIエージェント「Claude Code」の最新機能・使い方・プログラミングをAIで効率化する超実践術を解説! ↗

※ jpskill.com 編集部が参考用に選んだ動画です。動画の内容と Skill の挙動は厳密には一致しないことがあります。

📜 元の英語説明(参考)

Use when reading or writing TypeScript or JavaScript files (.ts, .tsx, .js, tsconfig.json).

🇯🇵 日本人クリエイター向け解説

一言でいうと

TypeScriptやJavaScriptのプログラムファイルを効率的かつ高品質に作成

※ jpskill.com 編集部が日本のビジネス現場向けに補足した解説です。Skill本体の挙動とは独立した参考情報です。

⚡ おすすめ: コマンド1行でインストール(60秒)

下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。

🍎 Mac / 🐧 Linux
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o typescript-best-practices.zip https://jpskill.com/download/4042.zip && unzip -o typescript-best-practices.zip && rm typescript-best-practices.zip
🪟 Windows (PowerShell)
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/4042.zip -OutFile "$d\typescript-best-practices.zip"; Expand-Archive "$d\typescript-best-practices.zip" -DestinationPath $d -Force; ri "$d\typescript-best-practices.zip"

完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。

💾 手動でダウンロードしたい(コマンドが難しい人向け)
  1. 1. 下の青いボタンを押して typescript-best-practices.zip をダウンロード
  2. 2. ZIPファイルをダブルクリックで解凍 → typescript-best-practices フォルダができる
  3. 3. そのフォルダを C:\Users\あなたの名前\.claude\skills\(Win)または ~/.claude/skills/(Mac)へ移動
  4. 4. Claude Code を再起動

⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。

🎯 このSkillでできること

下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。

📦 インストール方法 (3ステップ)

  1. 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
  2. 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
  3. 3. 展開してできたフォルダを、ホームフォルダの .claude/skills/ に置く
    • · macOS / Linux: ~/.claude/skills/
    • · Windows: %USERPROFILE%\.claude\skills\

Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。

詳しい使い方ガイドを見る →
最終更新
2026-05-17
取得日時
2026-05-18
同梱ファイル
1

💬 こう話しかけるだけ — サンプルプロンプト

  • Typescript Best Practices を使って、最小構成のサンプルコードを示して
  • Typescript Best Practices の主な使い方と注意点を教えて
  • Typescript Best Practices を既存プロジェクトに組み込む方法を教えて

これをClaude Code に貼るだけで、このSkillが自動発動します。

📖 Skill本文(日本語訳)

※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。

TypeScriptのベストプラクティス

CLAUDE.md に記載されている、型ファースト、関数型、エラーハンドリングのパターンに従います。このスキルは、言語固有のイディオムのみを扱います。

Reactのベストプラクティスと組み合わせる

Reactコンポーネント(.tsx.jsxファイル、または@reactインポート)を扱う際は、常にこのスキルと並行して react-best-practices をロードしてください。このスキルはTypeScriptの基本をカバーしています。React固有のパターン(エフェクト、フック、ref、コンポーネント設計)は、専用のReactスキルに含まれています。

不正な状態を表現不可能にする

型システムを使用して、コンパイル時に無効な状態を防止します。

相互排他的な状態のための判別共用体:

// Good: 有効な組み合わせのみが可能
type RequestState<T> =
  | { status: 'idle' }
  | { status: 'loading' }
  | { status: 'success'; data: T }
  | { status: 'error'; error: Error };

// Bad: { loading: true, error: Error } のような無効な組み合わせを許容する
type RequestState<T> = {
  loading: boolean;
  data?: T;
  error?: Error;
};

ドメインプリミティブのためのブランド型:

type UserId = string & { readonly __brand: 'UserId' };
type OrderId = string & { readonly __brand: 'OrderId' };

// コンパイラはUserIdが期待される場所にOrderIdを渡すことを防ぐ
function getUser(id: UserId): Promise<User> { /* ... */ }

リテラル共用体のためのconstアサーション:

const ROLES = ['admin', 'user', 'guest'] as const;
type Role = typeof ROLES[number]; // 'admin' | 'user' | 'guest'

// 配列と型は自動的に同期される
function isValidRole(role: string): role is Role {
  return ROLES.includes(role as Role);
}

neverチェックによる網羅的なswitch文:

type Status = "active" | "inactive";

function processStatus(status: Status): string {
  switch (status) {
    case "active":
      return "processing";
    case "inactive":
      return "skipped";
    default: {
      const _exhaustive: never = status;
      throw new Error(`unhandled status: ${_exhaustive}`);
    }
  }
}

Zodによるランタイム検証

  • スキーマを信頼できる唯一の情報源として定義し、z.infer<> でTypeScriptの型を推論します。型とスキーマの重複を避けてください。
  • 失敗が予想されるユーザー入力には safeParse を使用し、無効なデータがバグとなる信頼境界では parse を使用します。
  • DRYな定義のために、.extend().pick().omit().merge() でスキーマを構成します。
  • パース時のデータ正規化(文字列のトリム、日付のパース)のために .transform() を追加します。
import { z } from "zod";

const UserSchema = z.object({
  id: z.string().uuid(),
  email: z.string().email(),
  name: z.string().min(1),
  createdAt: z.string().transform((s) => new Date(s)),
});

type User = z.infer<typeof UserSchema>;

// 信頼境界での厳密なパース — API契約違反の場合にスローする
export async function fetchUser(id: string): Promise<User> {
  const response = await fetch(`/api/users/${id}`);
  if (!response.ok) {
    throw new Error(`fetch user ${id} failed: ${response.status}`);
  }
  return UserSchema.parse(await response.json());
}

// 呼び出し元はユーザー入力からの成功とエラーの両方を処理する
const result = UserSchema.safeParse(formData);
if (!result.success) {
  setErrors(result.error.flatten().fieldErrors);
  return;
}

オプション: type-fest

TypeScriptの組み込み機能を超える高度な型ユーティリティについては、type-fest を検討してください。

  • Opaque<T, Token> - 手動の & { __brand } パターンよりもクリーンなブランド型
  • PartialDeep<T> - ネストされたオブジェクトの再帰的なPartial
  • ReadonlyDeep<T> - 不変データのための再帰的なReadonly
  • SetRequired<T, K> / SetOptional<T, K> - ターゲットフィールドの変更
  • Simplify<T> - IDEのツールチップで複雑な交差型を平坦化
import type { Opaque, PartialDeep } from 'type-fest';

type UserId = Opaque<string, 'UserId'>;
type UserPatch = PartialDeep<User>;
📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開

TypeScript Best Practices

Follows type-first, functional, and error handling patterns from CLAUDE.md. This skill covers language-specific idioms only.

Pair with React Best Practices

When working with React components (.tsx, .jsx files or @react imports), always load react-best-practices alongside this skill. This skill covers TypeScript fundamentals; React-specific patterns (effects, hooks, refs, component design) are in the dedicated React skill.

Make Illegal States Unrepresentable

Use the type system to prevent invalid states at compile time.

Discriminated unions for mutually exclusive states:

// Good: only valid combinations possible
type RequestState<T> =
  | { status: 'idle' }
  | { status: 'loading' }
  | { status: 'success'; data: T }
  | { status: 'error'; error: Error };

// Bad: allows invalid combinations like { loading: true, error: Error }
type RequestState<T> = {
  loading: boolean;
  data?: T;
  error?: Error;
};

Branded types for domain primitives:

type UserId = string & { readonly __brand: 'UserId' };
type OrderId = string & { readonly __brand: 'OrderId' };

// Compiler prevents passing OrderId where UserId expected
function getUser(id: UserId): Promise<User> { /* ... */ }

Const assertions for literal unions:

const ROLES = ['admin', 'user', 'guest'] as const;
type Role = typeof ROLES[number]; // 'admin' | 'user' | 'guest'

// Array and type stay in sync automatically
function isValidRole(role: string): role is Role {
  return ROLES.includes(role as Role);
}

Exhaustive switch with never check:

type Status = "active" | "inactive";

function processStatus(status: Status): string {
  switch (status) {
    case "active":
      return "processing";
    case "inactive":
      return "skipped";
    default: {
      const _exhaustive: never = status;
      throw new Error(`unhandled status: ${_exhaustive}`);
    }
  }
}

Runtime Validation with Zod

  • Define schemas as single source of truth; infer TypeScript types with z.infer<>. Avoid duplicating types and schemas.
  • Use safeParse for user input where failure is expected; use parse at trust boundaries where invalid data is a bug.
  • Compose schemas with .extend(), .pick(), .omit(), .merge() for DRY definitions.
  • Add .transform() for data normalization at parse time (trim strings, parse dates).
import { z } from "zod";

const UserSchema = z.object({
  id: z.string().uuid(),
  email: z.string().email(),
  name: z.string().min(1),
  createdAt: z.string().transform((s) => new Date(s)),
});

type User = z.infer<typeof UserSchema>;

// Strict parsing at trust boundaries — throws if API contract violated
export async function fetchUser(id: string): Promise<User> {
  const response = await fetch(`/api/users/${id}`);
  if (!response.ok) {
    throw new Error(`fetch user ${id} failed: ${response.status}`);
  }
  return UserSchema.parse(await response.json());
}

// Caller handles both success and error from user input
const result = UserSchema.safeParse(formData);
if (!result.success) {
  setErrors(result.error.flatten().fieldErrors);
  return;
}

Optional: type-fest

For advanced type utilities beyond TypeScript builtins, consider type-fest:

  • Opaque<T, Token> - cleaner branded types than manual & { __brand } pattern
  • PartialDeep<T> - recursive partial for nested objects
  • ReadonlyDeep<T> - recursive readonly for immutable data
  • SetRequired<T, K> / SetOptional<T, K> - targeted field modifications
  • Simplify<T> - flatten complex intersection types in IDE tooltips
import type { Opaque, PartialDeep } from 'type-fest';

type UserId = Opaque<string, 'UserId'>;
type UserPatch = PartialDeep<User>;