关于 typescript
面向 TypeScript 5+ 项目的编码规范 Skill,帮助开发者编写或修改代码时加强类型建模、明确处理状态,并采用实用的编译器设置。
主要功能
- 01用品牌类型和联合类型建模领域
- 02优先使用 satisfies 而非类型断言
- 03用 const 对象替代 enum
- 04收窄 unknown 并隔离 any
- 05分离仅类型导入
- 06配置严格的编译器检查
适用场景
- 01为新编写的 TypeScript 代码应用规范
- 02检查代码变更中的类型安全问题
- 03设定 TypeScript 编译器基线
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ alexander-danilenko/ cortex-ai-skills --skill typescript安装后在 Claude Code 中输入/typescript确认已加载。
详细介绍
TypeScript
TypeScript 5+ 的团队约定。请应用于你编写或修改的代码;除非另有要求,否则不要为了符合约定而重构未触碰的文件。
约定
- 用类型建模领域,而不是用检查。 品牌类型(
type UserId = string & { readonly __brand: 'UserId' })和可辨识联合会在编译时暴露错误,几乎没有成本。运行时防护则会让同样的错误在生产环境中才被发现。 - 凡是有状态的情况,都使用可辨识联合——请求生命周期、表单状态、解析结果等。这样编译器会强制处理每种状态,新变体出现时也会作为错误暴露出来,而不是被静默跳过。
- 优先使用
satisfies,而不是as。satisfies会根据类型进行验证,同时保留较窄的推断字面类型;as则会绕过检查。只有在你掌握了编译器无法得知的信息时才使用as,并在注释中说明原因。 - 优先使用常量对象,而不是
enum。as const对象是普通值,不会生成代码,也不会带来名义类型上的意外;enum会生成运行时代码,而const enum在isolatedModules下会出问题。 any就是错误报告。 使用unknown并缩窄类型。如果边界处确实无法避免any,就将它隔离在一个适配器函数中,别让它扩散到各个调用点。- 单独导入类型(
import type { … })。打包器会干净地移除这些导入;混合导入可能会让你原本想移除的运行时依赖继续存在。 - 让类型推断发挥作用。 为导出接口和公共签名添加类型注解,让内部代码自行推断;过度注解只会增加噪声,并逐渐偏离实际类型。
- 作为库供他人使用的内容都要提供
.d.ts(declaration: true)。否则,使用者会退回到any,你的类型工作也就止步于包边界。 - 单体仓库:使用项目引用和
composite。 增量构建只会重新构建发生变化的部分;单一的扁平tsconfig则会在每次编辑时重新编译整个项目。
值得展示的两种惯用写法
只有强制检查穷尽性,它才真正成立。联合类型新增变体时,对它执行 switch 仍然可以顺利编译——assertNever 才能让每个需要更新的位置都报出构建错误:
function assertNever(x: never): never {
throw new Error(`Unhandled variant: ${JSON.stringify(x)}`);
}
function area(s: Shape): number {
switch (s.kind) {
case "circle":
return Math.PI * s.r ** 2;
case "rect":
return s.w * s.h;
default:
return assertNever(s); // add a variant → compile error here
}
}
只有在获取品牌类型的唯一途径是经过验证的函数时,品牌才有意义:
type Brand<T, B> = T & { readonly __brand: B };
type Email = Brand<string, "Email">;
export function toEmail(raw: string): Email {
if (!raw.includes("@")) throw new Error(`Not an email: ${raw}`);
return raw as Email;
}
构造函数中的 as 是唯一合理的用法——它位于验证边界,将未经验证的值转换为已验证的值。在其他任何地方将值断言为 Email,都会让整个类型设计失去意义。
tsconfig 基线
strict: true 并未启用所有值得开启的选项。请添加以下选项——每个选项都能捕获默认配置集遗漏的一类错误:
{
"compilerOptions": {
"strict": true,
"noUncheckedIndexedAccess": true,
"noPropertyAccessFromIndexSignature": true,
"noImplicitOverride": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"isolatedModules": true,
"declaration": true,
"skipLibCheck": true
}
}
noUncheckedIndexedAccess 是价值最高、也最难采用的选项:它会让 arr[i] 返回 T | undefined,这才符合实际情况。新项目请开启此选项;现有项目则要做好迁移准备。
模块解析:Node 运行输出时使用 NodeNext,由打包器处理时使用 bundler。
评论
支持 Markdown