TypeScript如何校验类型是否包含另一类型所有键且无额外键
实现方案
你可以通过给泛型添加条件约束来实现子集校验,核心是同时校验「TTo无额外键」和「对应键类型兼容」两个规则,完整实现如下:
function typeCheck<TFrom, TTo extends // 校验逻辑:如果TTo有TFrom之外的键,或者对应键类型不兼容,就返回never触发类型错误 Exclude<keyof TTo, keyof TFrom> extends never ? { [K in keyof TTo]: TFrom[K] } : never >(arg: TFrom): TTo { return arg as unknown as TTo; }
校验原理
Exclude<keyof TTo, keyof TFrom> extends never:提取TTo中所有不在TFrom里的键,如果结果不为never说明存在额外键,不满足约束{ [K in keyof TTo]: TFrom[K] }:要求TTo每个键的类型必须和TFrom中对应键的类型完全兼容,类型不匹配也会触发报错
用法示例
// 源类型 type User = { id: number; name: string; age: number; } // 合法场景:TTo是TFrom的子集,无额外键且类型匹配 type LegalSubset = { id: number; name: string; } // 无类型错误 const res1 = typeCheck<User, LegalSubset>({ id: 1, name: '小明', age: 20 }); // 非法场景1:存在额外键address(不在User键列表中) type BadSubset1 = { id: number; address: string; } // 触发类型报错 const res2 = typeCheck<User, BadSubset1>({ id: 1, name: '小明', age: 20 }); // 非法场景2:对应键类型不匹配(id类型从number变成了string) type BadSubset2 = { id: string; name: string; } // 触发类型报错 const res3 = typeCheck<User, BadSubset2>({ id: 1, name: '小明', age: 20 });
内容的提问来源于stack exchange,提问作者David Kváš
相关产品推荐
相关产品推荐

