TypeScript泛型中联合类型的多继承类型为何无法正常工作?
问题成因
这个编译错误是TypeScript严格模式下的预期检查结果,核心来自两条类型规则:
- 联合类型的访问限制:TypeScript对联合类型的成员访问有严格约束,只有当某个属性/索引在联合类型的所有分支上都合法存在时,才允许访问。只要有一个分支不支持该操作,就会抛出“属性不存在”的编译错误。
你的泛型参数T约束为MyStringKeyObject | MyNumberKeyObject,函数体内generic的静态类型为该联合类型,所有索引操作都需要同时满足两个分支的类型要求。你当前tsconfig开启了strict: true严格模式,这类不满足跨分支合法要求的访问会被直接拦截。 - 两类索引签名互相独立:TypeScript的静态检查不会因为JavaScript运行时数字键会自动转成字符串,就认为字符串索引签名兼容数字键访问,反之亦然:
- 仅声明
[key: string]索引签名的类型,只接受字符串类型的键做访问,不支持直接传入数字索引 - 仅声明
[key: number]索引签名的类型,只接受数字类型的键做访问,不支持任意字符串属性访问
- 仅声明
对应代码里的两处报错:
generic[1]使用数字键访问,但是MyStringKeyObject分支没有声明数字索引签名,不支持该操作generic.doesNotCompile使用自定义字符串属性访问,但是MyNumberKeyObject分支没有声明字符串索引签名,不支持该操作
复现问题代码
type MyStringKeyObject = { [key: string]: boolean; }; type MyNumberKeyObject = { [key: number]: boolean; }; const testFunction = <T extends MyStringKeyObject | MyNumberKeyObject>( generic: T ): void => { generic[1]; // 编译报错:数字类型不能作为该联合类型的索引 generic.doesNotCompile; // 编译报错:该属性不存在于联合类型上 };
补充说明
如果需要定义同时支持数字键、字符串键访问的类型,需要在类型中同时声明两类索引签名。TypeScript要求数字索引的返回值类型必须是字符串索引返回值类型的子类型,本例中二者返回值均为boolean,符合规则:
type MyDualKeyObject = { [key: string]: boolean; [key: number]: boolean; };
使用该类型作为泛型约束后,两类索引访问都可以正常通过编译。
内容的提问来源于stack exchange,提问作者rjumatov
相关产品推荐
相关产品推荐

