plugins/languages/typescript/skills/core/SKILL.md
TypeScript / JavaScript 核心开发规范,TS 6.0+ 严格模式优先,覆盖 tsconfig、Biome 2 / ESLint flat、pnpm 10 / Bun / Deno 2、Node 22-24 LTS、Vite 6 + Rolldown、Vitest 3、Zod 4。同时给出 JS-only 项目的 JSDoc + tsc --checkJs 兜底路径。Use when 新建 TS/JS 项目、配置 tsconfig、设置 linter/formatter、迁移 ESM、选型工具链,或用户提到 "TypeScript 规范"、"JS 规范"、"strict mode"、"tsconfig"、"biome"、"eslint"、"ESM"、"package manager"、"ES2025"。
npx skillsauth add lazygophers/ccplugin typescript-coreInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
本 skill 同时覆盖 JavaScript 项目;TypeScript 为首选,JS-only 写法见各节末尾兜底说明。
适用范围:所有 .ts / .tsx / .mts / .cts / .js / .jsx 源码。
类型安全 > 类型体操;编译期错误 > 运行期错误;显式 > 隐式。
strict: true + noUncheckedIndexedAccess + noImplicitOverride + exactOptionalPropertyTypesany — 用 unknown + 类型守卫,或 Zod 4 / Valibot 在边界验证"type": "module" + TS 用 import type 分离类型导入const 优先, let 次之, 禁 var.toSorted() / .toReversed() / .with() / structuredClone()any、@ts-ignore、enum (用 as const 对象代替)、namespacevar、require() / module.exports (ESM only)if (err) return err).eslintrc.js (旧) → flat config 或 Biomenode-fetch (Node 22+ 已内置 fetch)React.FC (隐式 children、泛型受限)console.log (用 pino 9 / console.warn / console.error)| 项 | 推荐 | 说明 |
|----|------|------|
| TypeScript | 6.0 稳定 | target: ES2025,strict 默认开 |
| TS 7.0 / tsgo | CI type-check 可用 | Go 重写 10x;emit 未 GA;用 @typescript/native-preview |
| 语言 | ES2025 + ES2026 stage 3+ | 兼容 ES2024 |
| Node.js | 22 LTS / 24 Active LTS | 原生 strip-types (22.18+)、原生 fetch、test runner |
| 运行时 | Node 22-24 / Bun 1.x / Deno 2 | 三选一 |
| 包管理 | pnpm 10 / Bun 1.x | 禁 npm 新项目 |
| Linter+Formatter | Biome 2 优先 / ESLint 9 flat (重 plugin 时) | Biome 2.3+ 423 规则 + 部分类型感知 |
| 测试 | Vitest 3.x | bench、type 测试、ESM 原生 |
| 构建 | Vite 6 (Rolldown) / tsdown / tsup | 库优先 tsdown |
| HTTP 框架 | Hono 4 / Fastify 5 | Express 5 (legacy) |
| 校验 | Zod 4 | Valibot / ArkType (小 bundle) |
{
"compilerOptions": {
"target": "ES2025",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"lib": ["ES2025"],
"strict": true,
"noUncheckedIndexedAccess": true,
"noImplicitOverride": true,
"noFallthroughCasesInSwitch": true,
"exactOptionalPropertyTypes": true,
"verbatimModuleSyntax": true,
"isolatedModules": true,
"esModuleInterop": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"declaration": true,
"sourceMap": true,
"outDir": "./dist"
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
// ES2025 - Iterator helpers
const evens = arr.values().filter(x => x % 2 === 0).take(10).toArray();
// ES2025 - Set methods
const u = a.union(b); const i = a.intersection(b); const d = a.difference(b);
// ES2025 - Object.groupBy / Map.groupBy
const byRole = Object.groupBy(users, u => u.role);
// ES2025 - Promise.try (同步异常进 Promise 链)
const p = Promise.try(() => mayThrowSync());
// ES2024 - Promise.withResolvers
const { promise, resolve, reject } = Promise.withResolvers();
// ES2025 - Array.fromAsync
const items = await Array.fromAsync(asyncIterable);
// ES2025 - RegExp /v flag
const re = /[\p{Emoji}--\p{ASCII}]/v;
// ES2026 stage 3 - using / await using
{
using file = openFile('data.txt');
await using db = await connectDB();
}
// Temporal (stage 3) - 替代 Date / moment
const now = Temporal.Now.zonedDateTimeISO();
// biome.json
{
"$schema": "https://biomejs.dev/schemas/2.3.0/schema.json",
"linter": {
"enabled": true,
"rules": {
"recommended": true,
"style": { "noVar": "error", "useConst": "error" },
"suspicious": { "noConsole": "warn" }
}
},
"formatter": { "enabled": true, "indentStyle": "space", "indentWidth": 2, "lineWidth": 100 },
"javascript": { "formatter": { "quoteStyle": "double", "semicolons": "always" } }
}
pnpm dlx @biomejs/biome init
pnpm biome check --write . # lint + format 一把梭
// eslint.config.ts (TS 项目)
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 },
},
rules: {
"@typescript-eslint/no-explicit-any": "error",
"@typescript-eslint/consistent-type-imports": ["error", { prefer: "type-imports" }],
},
},
);
type UserDTO = { id: string }; // 类型 PascalCase (禁 I 前缀)
type Status = "active" | "inactive";
const userName = "John"; // 变量 camelCase
function getUserById(id: string) { /* ... */ } // 函数 camelCase
const MAX_RETRIES = 3; // 常量 UPPER_SNAKE_CASE
// 文件 kebab-case: user-service.ts
// as const 替代 enum
const Role = { Admin: "admin", User: "user" } as const;
type Role = (typeof Role)[keyof typeof Role];
pnpm add -D @typescript/native-preview
pnpm exec tsgo --noEmit # CI 快速类型检查
# 注意:emit/decorators/older targets 尚未完整,构建仍用 tsc
若项目暂不切 TS,仍可获得 80% 类型保护:
// package.json
{ "type": "module" }
// jsconfig.json (或 tsconfig.json with allowJs)
{
"compilerOptions": {
"target": "ES2025",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"allowJs": true,
"checkJs": true, // 对 .js 也跑类型检查
"strict": true,
"noEmit": true,
"skipLibCheck": true
},
"include": ["src/**/*"]
}
// 用 JSDoc 标注类型,tsc 当 linter 用
/**
* @typedef {{ id: string; name: string; email: string }} User
*/
/**
* @param {string} id
* @returns {Promise<User>}
*/
export async function getUser(id) {
const r = await fetch(`/api/users/${id}`);
if (!r.ok) throw new Error(`HTTP ${r.status}`);
return /** @type {User} */ (await r.json());
}
# 类型检查 (零编译产物)
pnpm tsc --noEmit
Biome 2 / ESLint flat 对 JS 项目同样有效;JS 项目把上面 ESLint 示例去掉 tseslint,仅用 @eslint/js:
// eslint.config.js
import js from '@eslint/js';
export default [
js.configs.recommended,
{
files: ['src/**/*.{js,jsx}'],
rules: {
'no-var': 'error',
'prefer-const': 'error',
'no-console': ['warn', { allow: ['warn', 'error'] }],
},
},
];
迁移路线:JSDoc + checkJs → 文件级 .ts → 局部启 strict → 全量 strict。
| 现象 | 问题 | 严重 |
|------|------|------|
| any | 类型安全漏洞 | 高 |
| @ts-ignore | 隐藏真实错误 (用 @ts-expect-error + 注释) | 高 |
| var / require() | ESM / const / let | 高 |
| enum | tree-shaking 不友好 | 中 |
| .eslintrc.js | 旧 schema | 中 |
| 文件 > 500 行 | 拆分信号 | 中 |
| npm install 新项目 | pnpm/Bun 更优 | 中 |
| Jest 配置 | Vitest 3.x 替代 | 中 |
| 生产 console.log | pino 结构化输出 | 中 |
| 无运行时校验 | Zod 4 边界校验 | 高 |
| arr.sort() 变异 | arr.toSorted() | 中 |
strict: true + noUncheckedIndexedAccess + exactOptionalPropertyTypesany / @ts-ignore;JS: JSDoc + checkJs: trueas const 替代 enumimport type 分离类型导入"type": "module",ESM onlyconst/let,无 vartools
UI/UX 与布局设计——做界面布局/结构/导航/组件/交互的设计决策。触发:做UI/UX/布局/排版/导航/组件/交互/栅格/响应式/图表选型/字体配对。按媒介路由 HTML/Web、原生 App(iOS/Android/桌面)、CLI、TUI。需后端动态系统不适用;配色/主题/色板走姊妹 skill design-color。
tools
主题与配色设计——做颜色搭配/调色板/主题/品牌色阶/暗模式的设计决策。触发:选配色/调色/主题/色板/品牌色/暗模式/对比度/色盲/UI风格。按媒介路由 HTML/Web(CSS变量)、原生App(平台token)、CLI(ANSI)、TUI(真彩/256/16降级)。保证可访问性(对比度/色盲安全)。需后端动态系统不适用;UI/UX 布局/组件/交互走姊妹 skill design-uiux。
tools
跨任意组件(plugin/skill/agent/command)的验证驱动优化循环纪律 skill。当用户要优化某个已有组件却无明确方向、或要防止改了反而更差(自评乐观偏差 / 多维同改归因失效 / 为凑分加废话膨胀)、或要把一套通用「评分→单变量改→改后验证严格更好才留否则回滚→触顶停」的纪律套到任意组件上时使用。管优化过程本身的纪律(validation gate / ratchet / 独立验证 / 触顶停),不评单组件深度(交 skill-dev),不查插件接线(交 plugin-dev)。仅手动 /optimize-any 触发。
data-ai
两层规则记忆 (基于 .skein/spec)。planning 时 recall 召回相关规则、task finish 后 sediment 沉淀学习 + prune 自动精简过期/重复/断链规则。core 常驻硬规 + recall 按需召回, 经判定门自动写盘 (不逐次问用户)。产出 .skein/spec 下 core/recall 规则文件 + index。另支持空仓 bootstrap 播种规则基线、记忆大面积失效 (大重构/换栈) 时 reconstruct 可逆归档后按项目类型分型重建、maintain 手动体检 (超预算/stale/断链/重复/废弃, --apply 自动修复)、auto-fix (Stop hook 写 .pending-fix 标记 → main 派 skein-specer bg 跑 maintain --apply 全自动修, 断链只报告)。