TypeScript 如何定义属性名匹配固定模式且含固定字段的type
TypeScript 动态键类型实现方案
TS 4.4及以上版本已经原生支持模板字面量作为索引签名的键类型,完全可以实现你要的效果,无需宽泛索引签名或手动枚举。
核心实现代码
// 定义匹配id+数字规则的键类型 type IdPrefixedNumberKey = `id${number}`; // 组合固定属性和动态属性 type TargetType = { id: number; somethingElse: string; anotherOne: number; } & { [Key in IdPrefixedNumberKey]?: number; };
校验效果说明
- 符合规则的用例不会报错:
const validSample: TargetType = { id: 101, somethingElse: "demo", anotherOne: 202, id3: 303, id10086: 12345 };
- 不符合规则的用例会触发TS编译报错:
- 出现
idStr、id_123这类不符合id+数字格式的键 idxxx格式的键对应的值不是number类型- 缺少三个必填属性,或必填属性类型错误
- 出现
低版本TS兼容方案
如果使用的TS版本低于4.4,不支持模板字面量索引签名,最优替代方案是结合宽松基础类型+类型守卫做双重校验:
// 基础类型声明,固定属性严格校验,其他属性暂设为unknown type LegacyTargetType = { id: number; somethingElse: string; anotherOne: number; } & Record<string, unknown>; // 类型守卫函数,运行时校验所有动态键规则 function isValidTarget(obj: unknown): obj is LegacyTargetType { if (typeof obj !== "object" || obj === null) return false; const castObj = obj as LegacyTargetType; // 校验必填固定属性 if (typeof castObj.id !== "number") return false; if (typeof castObj.somethingElse !== "string") return false; if (typeof castObj.anotherOne !== "number") return false; // 校验所有id开头的键符合规则 for (const [key, val] of Object.entries(obj)) { if (!key.startsWith("id")) continue; const numSuffix = key.slice(2); // 仅校验符合id+数字格式的键的类型 if (/^\d+$/.test(numSuffix) && typeof val !== "number") { return false; } } return true; }
使用时先调用类型守卫做校验,后续代码即可获得完整的类型提示和校验。
内容的提问来源于stack exchange,提问作者Philipp Kyeck
相关产品推荐
相关产品推荐

