TypeScript泛型索引属性的keyof未正确限制参数选项问题
问题原因解析
问题出在显式类型标注导致TypeScript丢失了实例的具体类型信息,具体拆解如下:
类型收窄导致的信息丢失
你给instance显式标注了IHasIO类型,TypeScript会直接把instance的类型对齐到接口定义——而IHasIO里的outputs被定义为{[key: string]: string},也就是「任意字符串键的字符串值对象」。这时候keyof Outputs<typeof instance>等价于string,所以任何字符串参数(包括"c")都会被TypeScript判定为合法。正确的类型推断方式
如果你去掉显式的IHasIO标注,让TypeScript自动推断类型:const instance = { inputs: {}, outputs: { a: 'someValue', b: 'someOtherVal' } }此时
instance的类型会被推断为包含具体outputs键(a、b)的字面量类型,writeToOutput<typeof instance>的参数类型就会变成"a" | "b",自然就能正确限制只能传入这两个值。保留接口约束同时保留具体类型的方案
如果需要强制instance符合IHasIO接口,又想保留具体键的类型信息,可以用泛型工具函数实现:function createHasIO<T extends IHasIO>(obj: T): T { return obj; } const instance = createHasIO({ inputs: {}, outputs: { a: 'someValue', b: 'someOtherVal' } });这样
instance既满足IHasIO的约束,又保留了outputs的具体键类型,fn的参数就会被正确限制为"a" | "b"。
内容的提问来源于stack exchange,提问作者Oved D
相关产品推荐
相关产品推荐

