typescript-patterns

SKILL开发
开发 未标注权限 许可证不明确

TypeScript utility types and type-safe API design patterns. Use when designing type systems, creating utility types, or implementing type-safe patterns.

一句话选型结论

按资料字段整理

typescript-patterns是开发类的 Agent Skill,安装方式:GitHub 仓库,权限级别未标注,许可证不明确,没有现成安装命令,需按说明手动放置 SKILL.md。技能本质是给模型读的说明书,效果取决于模型与客户端;装完先用一个小任务验证,再放进正式流程。

分类开发 安装方式GitHub 仓库 权限级别未标注权限 许可证许可证不明确
累计安装 未标注 本周 未标注
GitHub 星标 0 仓库 agentic-knowledge-base
下载量 未标注 技能市场下载数
权限级别 未标注权限 安装前请确认风险范围
许可证 许可证不明确 未说明

安装

GitHub 仓库
在支持 Skills 的客户端里执行,装完问一句「你有哪些技能」验证
  1. 1
    确认客户端支持

    确认你的客户端支持 Skills(Claude、Codex、Cursor 等),并升级到较新的版本。

  2. 2
    拿到技能文件

    按安装说明或仓库 README,把 SKILL.md 放到客户端的 skills 目录(一般一个技能一个文件夹)。

  3. 3
    刷新技能列表

    重新打开客户端,或刷新技能列表,让新放进来的技能被加载。

  4. 4
    验证是否生效

    问一句「你有哪些技能」,确认列表里出现它,再拿一个小任务试跑。

技能档案

开发
字段来自技能仓库与公开索引,中文说明由本站标注
作者 / 维护方wlfmnstr仓库 agentic-knowledge-base · 版本 未标注
宿主客户端未标注技能可被这些客户端加载
安装方式GitHub 仓库安装包 wlfmnstr/agentic-knowledge-base
权限级别未标注权限安装前请确认风险范围
许可证未说明许可证不明确,商用前请自行确认条款
仓库可用性available技能仓库当前是否可访问
最近核验未标注上游最后核验时间 · 数据更新 未标注
正文体量9.7 KBSKILL.md 原文大小,越大说明说明书写得越细

典型使用场景

3 类
按分类整理的常见用法,具体以 SKILL.md 为准
写代码与改 bug

按需求补代码、定位并修掉报错。

读仓库与生成改动

让模型读懂项目结构,再给出可落地的改动。

跑测试与排查故障

按现象排查问题,补测试用例并复跑。

选择建议

装之前先看这几条
按条目字段给出的判断,不替你决定用不用

值得选的地方

  • 基础信息齐全,可以先按说明装一个试试。

先想清楚的地方

  • 没有标注权限级别,实际能做什么要装好后确认。
  • 许可证不明确,商用或二次分发前先到仓库确认条款。
  • 没有现成安装命令,要按安装说明或仓库 README 手动放置。
  • 没有做站内核验,内容以作者仓库为准。
  • 技能只是说明书,实际效果取决于模型与客户端,装完先用小任务试一遍。

更适合

  • 需要在开发场景里给模型补一套做法的人。
  • 愿意先读一遍 SKILL.md、确认它会让模型做什么的人。

不太适合

  • 对许可证要求很严、必须明确可商用的人。
  • 只想装完就自动变强、不打算看说明书的人。

同类对比

6 个同类
同分类里挑最接近的几条,字段以各自详情页为准
技能权限级别安装方式累计安装宿主客户端安装命令
typescript-patterns当前 未标注权限 GitHub 仓库 未标注 未标注 无
技能审查员 浏览器控制 ClawHub 市场 877.9 万 OpenClaw 有
Vercel React 最佳实践 浏览器控制 GitHub 仓库 849.1 万 Codex、Claude、Cursor 有
GitHub 代码协作 联网访问 ClawHub 市场 763.3 万 OpenClaw 有
网页设计指南 联网访问 GitHub 仓库 668.6 万 Codex、Claude、Cursor 有
本体论 只读 ClawHub 市场 663.7 万 OpenClaw 有

SKILL.md 全文

9.7 KB
模型实际读到的说明书原文,来自技能仓库

TypeScript Type Design Patterns

Utility Type Patterns

Built-in Utilities (Quick Reference)

// Selection
Pick<User, 'id' | 'name'>      // Select specific fields
Omit<User, 'password'>          // Exclude specific fields

// Modification
Partial<User>                   // All optional
Required<User>                  // All required
Readonly<User>                  // All readonly

// Mapping
Record<string, User>            // Object with User values

// Union manipulation
Exclude<'a' | 'b' | 'c', 'a'>  // 'b' | 'c'
Extract<'a' | 'b', 'a' | 'c'>  // 'a'
NonNullable<T | null>           // T

// Function utilities
ReturnType<typeof fn>           // Extract return type
Parameters<typeof fn>           // Extract parameter types

Custom Utility Types

Make specific fields optional:

type Optional<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;

type UserUpdate = Optional<User, 'email' | 'avatar'>;

Deep Partial:

type DeepPartial<T> = {
  [P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
};

Nullable:

type Nullable<T> = T | null;

Discriminated Unions

Pattern

type Result<T> =
  | { success: true; data: T }
  | { success: false; error: string };

function handle<T>(result: Result<T>) {
  if (result.success) {
    // TypeScript knows result.data exists
    console.log(result.data);
  } else {
    // TypeScript knows result.error exists
    console.log(result.error);
  }
}

Critical: Discriminant must be a literal type (true, 'loading', etc.).

API Response Pattern

type ApiResponse<T> =
  | { status: 'idle' }
  | { status: 'loading' }
  | { status: 'success'; data: T }
  | { status: 'error'; error: Error };

Generic Type Design

Constraints

// Constrain to objects with specific properties
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
  return obj[key];
}

// Constrain to specific shape
function processEntity<T extends { id: string }>(entity: T) {
  return entity.id;
}

// Multiple constraints
function merge<T extends object, U extends object>(a: T, b: U): T & U {
  return { ...a, ...b };
}

Default Type Parameters

interface ApiResponse<T = unknown> {
  data: T;
  status: number;
}

// Can omit type parameter
const response: ApiResponse = { data: "anything", status: 200 };

// Or provide specific type
const typed: ApiResponse<User> = { data: user, status: 200 };

Type Guards

Custom Type Guards

interface User {
  type: 'user';
  name: string;
}

interface Admin {
  type: 'admin';
  name: string;
  permissions: string[];
}

// Type predicate
function isAdmin(user: User | Admin): user is Admin {
  return user.type === 'admin';
}

// Usage
if (isAdmin(user)) {
  // TypeScript knows user is Admin
  console.log(user.permissions);
}

Assertion Functions

function assertIsDefined<T>(value: T): asserts value is NonNullable<T> {
  if (value === null || value === undefined) {
    throw new Error('Value is null or undefined');
  }
}

function process(value: string | null) {
  assertIsDefined(value);
  // TypeScript knows value is string here
  return value.toUpperCase();
}

Conditional Types

Basic Pattern

type IsString<T> = T extends string ? true : false;

type A = IsString<string>; // true
type B = IsString<number>; // false

Extract Return Type

type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never;

function getUser() {
  return { id: '1', name: 'Alice' };
}

type User = ReturnType<typeof getUser>;  // { id: string; name: string }

Unwrap Promise

type Unwrap<T> = T extends Promise<infer U> ? U : T;

type Result = Unwrap<Promise<string>>;  // string
type Direct = Unwrap<number>;           // number

Mapped Types

Transform Properties

// Make all properties optional
type Optional<T> = {
  [P in keyof T]?: T[P];
};

// Make all properties readonly
type Readonly<T> = {
  readonly [P in keyof T]: T[P];
};

// Transform all to string
type Stringify<T> = {
  [P in keyof T]: string;
};

Conditional Property Types

// Make all properties nullable
type Nullable<T> = {
  [P in keyof T]: T[P] | null;
};

Template Literal Types

String Manipulation

// Capitalize
type Greeting = `Hello ${string}`;

// Event names
type EventName = 'click' | 'hover' | 'focus';
type Handler = `on${Capitalize<EventName>}`;
// 'onClick' | 'onHover' | 'onFocus'

// Combine literals
type Color = 'red' | 'blue';
type Size = 'sm' | 'lg';
type Variant = `${Color}-${Size}`;
// 'red-sm' | 'red-lg' | 'blue-sm' | 'blue-lg'

Type-Safe Event Emitters

type EventMap = {
  'user:login': { userId: string; timestamp: Date };
  'user:logout': { userId: string };
  'data:update': { id: string; data: unknown };
};

class TypedEmitter {
  on<K extends keyof EventMap>(
    event: K,
    handler: (data: EventMap[K]) => void
  ): void {
    // Implementation
  }

  emit<K extends keyof EventMap>(
    event: K,
    data: EventMap[K]
  ): void {
    // Implementation
  }
}

// Usage is fully type-safe
const emitter = new TypedEmitter();
emitter.on('user:login', (data) => {
  // data is typed as { userId: string; timestamp: Date }
  console.log(data.userId);
});

Branded Types

Create distinct types from same primitive:

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

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

function getUser(id: UserId) { /* ... */ }

const userId = createUserId('user-123');
const productId = 'product-456' as ProductId;

// This is a type error:
// getUser(productId);  // ProductId is not assignable to UserId

Use when: Need to distinguish same-typed values (IDs, tokens, etc.).

Interface vs Type

Use Interface for:
- Object shapes
- When extension is expected
- Class contracts

Use Type for:
- Unions
- Tuples
- Complex computed types
- When using utility types

// Interface - extensible
interface User {
  id: string;
  name: string;
}

interface Admin extends User {
  role: 'admin';
}

// Type - unions
type Status = 'idle' | 'loading' | 'success' | 'error';

type Result<T> =
  | { success: true; data: T }
  | { success: false; error: string };

tsconfig.json Essential Settings

{
  "compilerOptions": {
    // Strict type checking
    "strict": true,
    "noUncheckedIndexedAccess": true,
    "noImplicitOverride": true,
    "exactOptionalPropertyTypes": true,

    // Module resolution
    "moduleResolution": "bundler",
    "module": "ESNext",
    "target": "ES2022",

    // Emit
    "declaration": true,
    "sourceMap": true,

    // Interop
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "forceConsistentCasingInFileNames": true,

    // Performance
    "skipLibCheck": true,

    // Path mapping
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"]
    }
  }
}

Always enable: strict, noUncheckedIndexedAccess, forceConsistentCasingInFileNames

Best Practices

1. Avoid any

// Bad
function process(data: any) {
  return data.value;
}

// Good - use proper types
function process(data: { value: string }) {
  return data.value;
}

// Good - use unknown for truly unknown
function parse(json: string): unknown {
  return JSON.parse(json);
}

2. Use const Assertions

// Instead of
const colors = ['red', 'blue']; // string[]

// Use const assertion
const colors = ['red', 'blue'] as const; // readonly ['red', 'blue']

// For objects
const config = {
  apiUrl: 'https://api.example.com',
  timeout: 5000,
} as const;

3. Prefer Union Types Over Enums

// Instead of enum
enum Status {
  Idle = 'idle',
  Loading = 'loading',
}

// Prefer union type
type Status = 'idle' | 'loading' | 'success' | 'error';

Why: Simpler, more flexible, better tree-shaking.

4. Use readonly for Immutability

interface User {
  readonly id: string;
  name: string;
}

function processItems(items: readonly string[]) {
  // Cannot mutate items
  return items.join(',');
}

5. Type Narrowing

function process(value: string | number | null) {
  // Null check
  if (value === null) return 'null';

  // typeof check
  if (typeof value === 'string') {
    return value.toUpperCase();
  }

  // TypeScript knows value is number here
  return value.toFixed(2);
}

Common Pitfalls

Type assertions (as) - Use sparingly:

// Avoid when possible
const user = data as User;

// Better: Validate at runtime
if (isUser(data)) {
  // data is User here
}

Non-null assertion (!) - Dangerous:

// Avoid
const user = getUser()!;

// Better: Handle null
const user = getUser();
if (user) {
  // Use user safely
}

Empty object type {} - Too permissive:

// Bad
const config: {} = 'anything';

// Good
const config: object = { key: 'value' };
const settings: Record<string, unknown> = { key: 'value' };

Type Design Checklist

When designing types:
- [ ] Use strict mode
- [ ] Avoid any - use unknown or proper types
- [ ] Use discriminated unions for state
- [ ] Use const assertions for literal types
- [ ] Prefer interfaces for objects, types for unions
- [ ] Use readonly where appropriate
- [ ] Provide good error messages (use descriptive types)
- [ ] Consider future extension needs

常见问题

5 问
答案由本站依据条目字段整理
typescript-patterns怎么安装?

没有现成安装命令:按安装说明或仓库 README,把 SKILL.md 放进客户端的 skills 目录(一般一个技能一个文件夹)。

typescript-patterns支持哪些客户端?

资料没有标注宿主客户端,但只要客户端支持 Skills(Claude、Codex、Cursor 等),一般都能加载。

typescript-patterns权限高吗,安全吗?

权限级别为未标注权限。安装前先看它会读取或写入哪些内容。

typescript-patterns收费吗?

本站不代收费用,也没有标注具体价格。是否收费取决于技能本身和所用的模型或客户端,正式使用前按作者说明确认。

typescript-patterns用什么许可证?

许可证标注为 未说明(许可证不明确)。商用或二次分发前请到仓库确认条款原文。

热门专题

按场景挑技能
全部专题 →

技能内容以作者仓库为准;分类、权限级别与许可证状态的中文说明为中文整理,最近核验 未标注。