使用keyof创建的类型无法索引原类型的TypeScript问题
解决TypeScript联合类型下的索引类型报错问题
你遇到的问题是因为TypeScript对联合类型的索引处理比较严格:当T是User | House的子集时,T['data']会被解析成User['data'] | House['data']的联合类型。虽然你的泛型已经约束了K是当前T['data']的键,但TypeScript无法确定这个K能同时适用于联合类型中的所有成员,所以抛出了索引不兼容的错误。
给你两种可行的解决方法:
方法一:类型断言(快速解决)
直接把obj.data断言为T['data'],明确告诉TypeScript当前的obj.data就是对应T的data类型,这样就能正常索引了:
interface User { data: { id: number; name: string; } } interface House { data: { number: number; street: string; } } type Obj = User | House; function getProperty< T extends Obj, K extends keyof T['data'] >(obj: T, key: K): T['data'][K] { // 添加类型断言消除报错 return (obj.data as T['data'])[key]; } const user: User = { data: { id: 1, name: "Alice" }}; const house: House = { data: { number: 2, street: "First" }}; const userName = getProperty(user, "name"); // 类型推断为string const houseNumber = getProperty(house, "number"); // 类型推断为number
方法二:重构泛型约束(更优雅的长期方案)
把带data属性的结构抽成通用泛型接口,让函数直接针对这个通用结构做约束,避免联合类型带来的歧义:
// 定义通用的带data属性的类型 interface WithData<D> { data: D; } // 原有类型基于通用接口定义 interface User extends WithData<{ id: number; name: string }> {} interface House extends WithData<{ number: number; street: string }> {} // 重构后的工具函数 function getProperty<D, K extends keyof D>(obj: WithData<D>, key: K): D[K] { return obj.data[key]; // 此处无类型报错 } const user: User = { data: { id: 1, name: "Alice" }}; const house: House = { data: { number: 2, street: "First" }}; const userName = getProperty(user, "name"); const houseNumber = getProperty(house, "number");
这种方式不仅解决了当前的报错,还让工具函数的复用性更强——后续新增类似的带data属性的类型时,只要继承WithData接口就能直接使用getProperty函数。
内容的提问来源于stack exchange,提问作者bothears
相关产品推荐
相关产品推荐

