为什么打字稿不能在这里推断类型参数"T"的"T[键]"的类型?



我正试图编写一个通用类,该类传递一个键key,对应于一组已知的构造接口之一的键,以后可以传递一个对象thing和类型安全访问thing[key]。这是我得到的:

interface AB {
a: string
b: number
}
interface BC {
b: number
c: Date
}
type ABC = AB | BC
class Getter<T extends ABC> {
key: keyof T;
constructor(key: keyof T) {
this.key = key;
}
get(thing: T): string {
const value = thing[this.key];
return value.toString();
}

}
const getter = new Getter<AB>('b');

操场上联系

在这里,我希望Typescript推断,因为T extends ABC,T[keyof T]=AB[keyof AB] | BC [keyof BC]=string | number | date。然而,它似乎被困在T[keyof T]。即使在该行添加as AB[keyof AB] | BC[keyof BC]也不能修复它,我需要as unknown as AB[keyof AB] | BC[keyof BC]!没有那条线,有没有办法让它工作?

还有,我是否可以将key的值作为类型参数化,而不是将thing的类型参数化?

T extends ABC时,它可以有许多其他属性和类型。因此不能有.toString()方法。

type G = {
a: string;
b: number;
hello: undefined;
};
const g = new Getter<G, keyof G>("hello");
g.get({
a: "a",
b: 1,
hello: undefined
}); // undefined does not have .toString() method

操场上联系

是否有任何方法可以将key的值参数化为类型而不是参数化事物的类型?

是的,没有比这更容易的了。

class Getter<Key extends string | symbol> {
key: Key;
constructor(key: Key) {
this.key = key;
}
get(thing: {[k in Key]: string | number | Date}): string {
const value = thing[this.key];
return value.toString();
}
}

<一口>(操场演示)

这仅仅是打字脚本本质的限制。您需要检查成员,然后在运行时执行类型强制转换。希望这对你有帮助!

例如:

if (AnimalObject.Object.Keys().Includes('Name')) {
// We now know the generic type has a matching member
}

至于实现,我将创建一个'T'可以使用的接口列表,然后为每个接口创建一个成员数组,按照上面的逻辑,你可能会得到这样的结果:

// Store your valid types for checking
const ValidInterfacesSet: any[] = {Dog,Cat,car,Mammal};
//Look through members and confirm them... 
GetAndCastType(typeToCheck: any) {
typeToCheckKeys: string = typeToCheck.Object.keys();
for (inter: any of ValidInterfacesSet) {
const interMemberNames: string[] = inter.object.keys();

if(array1.sort().join(',')=== array2.sort().join(',')) {
// Returning the casted type if the iter members contain the same as typeToCheckMembers
return typeToCheck as inter; 
}
}
}

最新更新