Typescript Type Safety
/install fec-typescript-type-safety
TypeScript 类型安全
Purpose
为前端代码建立可演进的类型契约,减少 any、断言和运行时形状漂移。
Procedure
1. 先确定类型边界
把类型分为外部输入、领域模型、UI view model、组件 props、工具函数 API。不要让后端 DTO、表单模型和 UI 展示模型互相冒充。
interface UserDto {
id: string;
display_name: string;
status: "ACTIVE" | "DISABLED";
}
interface UserViewModel {
id: string;
displayName: string;
status: "active" | "disabled";
}
export function mapUserDto(dto: UserDto): UserViewModel {
return {
id: dto.id,
displayName: dto.display_name,
status: dto.status === "ACTIVE" ? "active" : "disabled",
};
}
2. 用 unknown 和收窄处理不可信数据
外部输入先校验再使用。不要用 as 让编译器闭嘴。
interface ApiErrorBody {
message: string;
}
function isApiErrorBody(value: unknown): value is ApiErrorBody {
return (
typeof value === "object" &&
value !== null &&
"message" in value &&
typeof value.message === "string"
);
}
export function getApiErrorMessage(value: unknown): string {
return isApiErrorBody(value) ? value.message : "Unexpected error";
}
3. 用判别联合表达状态机
异步状态、权限分支、支付状态等有限状态,用判别字段让新增分支在编译期暴露。
type Loadable\x3CT> =
| { state: "idle" }
| { state: "loading" }
| { state: "success"; data: T }
| { state: "error"; error: Error };
function assertNever(value: never): never {
throw new Error(`Unhandled state: ${JSON.stringify(value)}`);
}
export function renderUserState(user: Loadable\x3C{ name: string }>): string {
switch (user.state) {
case "idle":
return "Ready";
case "loading":
return "Loading";
case "success":
return user.data.name;
case "error":
return user.error.message;
default:
return assertNever(user);
}
}
4. 让泛型服务调用方,而不是炫技
泛型应减少重复并保持调用方推断清晰。复杂类型超过阅读成本时,优先拆具名类型。
interface SelectOption\x3CTValue extends string | number> {
label: string;
value: TValue;
}
interface SelectProps\x3CTValue extends string | number> {
value: TValue;
options: Array\x3CSelectOption\x3CTValue>>;
onChange: (value: TValue) => void;
}
export function Select\x3CTValue extends string | number>({
value,
options,
onChange,
}: SelectProps\x3CTValue>) {
return (
\x3Cselect value={value} onChange={(event) => onChange(event.target.value as TValue)}>
{options.map((option) => (
\x3Coption key={option.value} value={option.value}>
{option.label}
\x3C/option>
))}
\x3C/select>
);
}
5. 用类型测试保护公共类型
公共工具类型、组件库类型和 SDK 类型,应有轻量类型测试或编译期断言。
type Equal\x3CTLeft, TRight> =
(\x3CT>() => T extends TLeft ? 1 : 2) extends \x3CT>() => T extends TRight ? 1 : 2
? true
: false;
type Expect\x3CT extends true> = T;
type UserStatus = UserViewModel["status"];
type _UserStatusTest = Expect\x3CEqual\x3CUserStatus, "active" | "disabled">>;
详细参考
涉及高级泛型约束、映射类型、模板字面量类型、类型测试、DTO 映射或类型审查清单时,加载 references/type-safety-patterns.md。
Constraints
- 避免
any、无守卫的非空断言和不相关类型之间的强制as。 - 不把大型匿名类型堆在函数参数或 JSX props 上;提取具名类型表达业务含义。
- 不为简单业务过度设计递归条件类型;类型复杂度应服务可维护性。
- 公共 API 的输入输出必须显式标注,局部变量可依赖推断。
- 类型建模不能替代运行时校验;外部数据仍需 schema 或 type guard。
Expected Output
产出清晰的类型边界、可收窄的数据模型、必要的类型测试和验证命令。评审时应列出类型风险、运行时影响、推荐建模方式和是否需要专项修复。
- Make sure OpenClaw is installed (local or Docker)
- Run the install command in chat:
/install fec-typescript-type-safety - After installation, invoke the skill by name or use
/fec-typescript-type-safety - Provide required inputs per the skill's parameter spec and get structured output
What is Typescript Type Safety?
Use when designing, implementing, or reviewing TypeScript type contracts, advanced generics, discriminated unions, type guards, API DTOs, component props, pu... It is an AI Agent Skill for Claude Code / OpenClaw, with 29 downloads so far.
How do I install Typescript Type Safety?
Run "/install fec-typescript-type-safety" in the OpenClaw or Claude Code chat to install it in one step — no extra setup required.
Is Typescript Type Safety free?
Yes, Typescript Type Safety is completely free, licensed under MIT-0. You can download, install and use it at no cost.
Which platforms does Typescript Type Safety support?
Typescript Type Safety is cross-platform and runs anywhere OpenClaw / Claude Code is available (cross-platform).
Who created Typescript Type Safety?
It is built and maintained by Bovin Phang (@bovinphang); the current version is v2.5.0.