class Component { }
class ShallowWrapper { }
// generic P is a simple object
class TestContainer<T extends Component, P extends object>
{
constructor(reactElement: T, selectors: P) {
// iterate over selectors and define object properties
}
initialize(): void { }
[elem: keyof P]: any
// I need to define class properties based on P's keys
// -- compiler throws --
// An index signature parameter type cannot be a union type.
// Consider using a mapped object type instead.
}
const p = new TestContainer(new Component, { test: 'a' });
const v = p.test // this throws a type error (property does not exist)
在上面的代码中,我尝试基于泛型参数P动态定义对象属性。但是编译器抛出错误
索引签名参数类型不能是联合类型。考虑 改为使用映射的对象类型。
我该如何解决这个问题?
答案 0 :(得分:1)
编译器会为您提供此错误,因为您尝试将索引签名参数的语法与映射类型的语法混合使用。索引签名参数可能只有string
或number
类型。
您可以使用工厂方法通过强类型实现您想要的效果:
class Component { }
class TestContainer<T extends Component> {
static create<T extends Component, P extends object>(reactElement: T, selectors: P) {
return Object.assign(new TestContainer(reactElement), selectors);
}
private constructor(reactElement: T) {}
}
const p = TestContainer.create(new Component(), { test: 'a' });
const v = p.test;
顺便说一下,我不知道你是否将Component
弄空了以便插图,但是你绝不应该使用空类来限制类型。由于TypeScript使用结构类型系统,因此空类在结构上等同于Object
。这意味着T extends Component
基本上没用,因为它与T extends Object
相同,后者又与T
相同。如果您尝试它,您将看到以下内容有效:
TestContainer.create(42, { test: 'a' })