スキル一覧に戻る
derseitenschneider

typescript-patterns

by derseitenschneider

0🍴 0📅 2026年1月21日
GitHubで見るManusで実行

SKILL.md


name: typescript-patterns description: Best practices for TypeScript types, interfaces, assertions, and type safety. Use when writing or reviewing TypeScript code.

TypeScript Patterns Skill

Best practices for types, interfaces, assertions, and type safety.

Type Inference Over Explicit Returns

// ✅ Inferred return type
function calculateTotal(items: OrderItem[]) {
  return items.reduce((sum, item) => sum + item.price, 0);
}

// ❌ Explicit return type
function calculateTotal(items: OrderItem[]): number {
  return items.reduce((sum, item) => sum + item.price, 0);
}

Why: Inference catches implicit type coercion bugs.

Runtime Type Assertions

Never hard cast from JSON.parse. Validate at runtime.

// ❌ Hard cast
const value: MyType = JSON.parse(message);

// ✅ Runtime assertion
function isMyType(value: unknown): value is MyType {
  return (
    typeof value === "object" &&
    value !== null &&
    typeof (<MyType>value).prop === "string"
  );
}

const value = JSON.parse(message);
assert(isMyType(value), "Invalid message format");

Type Assertion Functions

// Parameter: 'value' with 'unknown' type
// Always return boolean, never throw
function isStrategy(value: unknown): value is Strategy {
  return (
    typeof value === "object" &&
    value !== null &&
    typeof (<Strategy>value).name === "string"
  );
}

// Use with assert
assert(isStrategy(value), "Value is not a valid Strategy");

Interfaces vs Types

// Interface for module-scope object types
export interface Product {
  id: string;
  name: string;
  price: number;
}

// Type for local function-scoped types
function validate(input: unknown) {
  type Result = { errors: string[]; valid: boolean };
  const output: Result = { errors: [], valid: true };
  // ...
}

// Type for unions
type Status = "pending" | "active" | "inactive";

Casting Syntax

// ✅ Angle bracket syntax
const x = <number>y;
const config = <ConfigType>JSON.parse(json);

// ❌ 'as' syntax
const x = y as number;

Interface Conventions

  • No I prefix or Data suffix
  • Properties in alphabetical order
  • Think of interfaces as nouns or adjectives (Shippable, Refundable)
  • When extending, inherit ALL properties (no Omit)
// Adjective interfaces
interface Shippable {
  shipping_address: string;
  shipping_cost: number;
}

// Concrete interface
interface Order extends Shippable {
  id: string;
  total: number;
}

Enums

Use explicit values. Prefer union types for small sets.

// ✅ Explicit string enum (4+ values)
export enum TenantModel {
  USER = "user",
  ORGANIZATION = "organization",
  EMPLOYER = "employer",
}

// ✅ Union type (2-3 values)
type Status = "active" | "inactive";

// Validate with Object.values
if (!Object.values(AttributionModel).includes(model)) {
  throw new Error("Invalid model");
}

Iteration

// ✅ for...of loop
for (const item of items) {
  processItem(item);
}

// ❌ forEach
items.forEach((item) => {
  processItem(item);
});

Why: for...of works with break, continue, return, await, and has better debugging/stack traces.

Use map/filter/reduce for transformations, not side effects.

Import Style

// ✅ Namespace imports
import * as mongodb from "mongodb";
import * as Types from "./types/index.js";

// ❌ Default imports
import MongoDB from "mongodb";

Organization

  • Only export types that are part of public API
  • Use ReturnType and Parameters to access private types

スコア

総合スコア

50/100

リポジトリの品質指標に基づく評価

SKILL.md

SKILL.mdファイルが含まれている

+20
LICENSE

ライセンスが設定されている

0/10
説明文

100文字以上の説明がある

0/10
人気

GitHub Stars 100以上

0/15
最近の活動

3ヶ月以内に更新がある

0/10
フォーク

10回以上フォークされている

0/5
Issue管理

オープンIssueが50未満

+5
言語

プログラミング言語が設定されている

+5
タグ

1つ以上のタグが設定されている

0/5

レビュー

💬

レビュー機能は近日公開予定です