如何在TypeScript中兼顾规则类型校验与VS Code自动补全?
解决方案
要同时实现rules的类型校验和variants中规则名称的自动补全,可以通过以下两种方式实现:
方法一:使用satisfies操作符(TypeScript 4.9+ 推荐)
satisfies操作符专门用于解决「校验类型兼容性但保留原字面量类型」的场景,是最简洁的方案:
type Rule = Record<string, () => Promise<void>>; // 用satisfies确保rules符合Rule类型,同时保留字面量类型 const rules = { 'Belgium': async () => { // 规则逻辑 }, // 若添加不符合Rule的属性(比如非函数值),TS会直接报错 // 'InvalidRule': 123 // 类型错误 } as const satisfies Rule; type RuleName = keyof typeof rules; // 类型为具体的 'Belgium',而非string type Variant = { customer: { crmId: string, name: string, }, rules: RuleName[], }; const variants: Variant[] = [ { customer: { crmId: 'NL21040010', name: 'ACME', }, rules: [ 'Belgium' ], // VS Code提供自动补全 }, { customer: { crmId: 'BE13120059', name: 'John Doe Inc.', }, rules: [ 'Belgium'] // 同样支持补全 } ];
方法二:泛型辅助函数(兼容低版本TypeScript)
如果你的TypeScript版本低于4.9,可以用泛型函数来约束类型并保留字面量信息:
type Rule = Record<string, () => Promise<void>>; // 泛型函数约束输入符合Rule类型,同时返回原字面量类型 const createRules = <T extends Rule>(rules: T) => rules; const rules = createRules({ 'Belgium': async () => { // 规则逻辑 }, // 不符合Rule的属性会触发类型错误 // 'InvalidRule': 'not a function' // 类型错误 } as const); type RuleName = keyof typeof rules; // 类型为 'Belgium' type Variant = { customer: { crmId: string, name: string, }, rules: RuleName[], }; const variants: Variant[] = [ { customer: { crmId: 'NL21040010', name: 'ACME', }, rules: [ 'Belgium' ], // 自动补全生效 }, { customer: { crmId: 'BE13120059', name: 'John Doe Inc.', }, rules: [ 'Belgium'] } ];
这两种方案都能同时满足:
rules必须符合Rule类型的结构约束variants中的rules数组能获得具体规则名称的自动补全
内容的提问来源于stack exchange,提问作者Patrick Miah
相关产品推荐
相关产品推荐

