TypeScript中如何定义继承基础索引类型且保留自动补全的具象接口
问题本质
你遇到的报错是TypeScript的固有类型限制:显式定义的接口如果没有声明索引签名,是不能直接赋值给带字符串索引签名的类型的。而给接口继承索引签名会让keyof直接返回string类型,自然丢失精确的键提示。
解决方案
你不需要将泛型约束为「继承带索引签名的basic类型」,只要修改泛型约束为「类型所有属性值均为number」即可,同时保留精确的类型提示:
// 原有basic类型可以保留用于其他场景,不影响 type basic = { [key: string]: number } // 泛型约束修改为:所有自有属性的值都是number即可,不要求支持任意字符串索引 class A<TInput extends Record<keyof TInput, number>> { // 类内部原有逻辑不需要改动 } interface moreConcrete { a: number, b: number } const test = new A<moreConcrete>(); // 不再报错 // keyof只会识别接口显式定义的键,非法赋值会直接触发报错 const typeTest: keyof moreConcrete = 'as'; // 报错:不能将类型"as"分配给类型"a" | "b"
如果类A内部需要通过任意字符串索引读取属性,只需要在内部读取时增加类型断言即可,不会污染外部使用的类型提示:
class A<TInput extends Record<keyof TInput, number>> { constructor(private input: TInput) {} getVal(key: string): number { return this.input[key as keyof TInput] as number; } }
内容的提问来源于stack exchange,提问作者Adam Baranyai
相关产品推荐
相关产品推荐

