我正在编写一个实例化的类,该类具有一个方法,该方法的返回类型是一个对象,其键来自编译器推断的泛型类型。我遇到了以下代码片段的问题,因为编译器告诉我通用类型 U
不能按 T
类型索引——我认为这是不正确的,因为事实上 U
是使用 T
进行类型映射的,因此 T 总是能够索引类型为 U
的对象。有没有办法向编译器确认是这种情况?
最小片段:
class DynamicReturnFormat<T extends string, U = { [ key in T ]: string }> {
constructor(private keys: T[]) {}
public returnObject(): U {
const obj = {} as U;
for (const key of this.keys) {
obj[key] = "test";
// error TS2536: Type 'T' cannot be used to index type 'U'.
}
return obj;
}
}
根据 Rich N. 的回答,这个类将按如下方式使用:
declare const input: Buffer;
const fmt = ["length", "packetID", ...];
const handshakeParser = new DataParser(fmt);
const decodedObject = handshakeParser.decode(input);
对于上下文:DynamicReturnFormat
是DataParser
,returnObject
是decode
。我希望 decodedObject
有一个非“一刀切”的类型,它只包含传递到类实例化中的属性。
最佳答案
有点不清楚你希望如何使用它,但我猜你想做类似的事情:
const keys = ["a", "b", "c"];
const drf = new DynamicReturnFormat(keys);
const result = drf.returnObject();
那么结果应该是{a: "test", b: "test", c: "test"}?
如果是这样,下面的代码就可以工作了。我不得不取出第二个通用变量 U,并使用 Partial 作为 {} 不可分配给类型 {[key in T]: string}:
class DynamicReturnFormat<T extends string> {
constructor(private keys: T[]) { }
public returnObject(): { [key in T]: string } {
const obj: Partial<{ [key in T]: string }>= {};
for (const key of this.keys) {
obj[key] = "test";
}
return obj as { [key in T]: string };
}
}
上面的代码有效,但我认为泛型 T 并没有增加太多值(value)。如果您希望以某种方式限制传递给构造函数的数组,我认为这不能以这种方式完成(?)。所以下面的代码可能会更好:
class DynamicReturnFormat {
constructor(private keys: string[]) { }
public returnObject(): { [key: string]: string } {
const obj: { [key: string]: string } = {};
for (const key of this.keys) {
obj[key] = "test";
}
return obj;
}
}
关于 typescript :类型映射类型不能用原始类型索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63328745/