我正在尝试将注册表对象移植到Typescript。它具有基于传入对象的属性而动态命名的属性。我现在可能不会以这种方式设计它,但是有大量的代码库按原样使用它,并且围绕它获得良好的类型def是对其进行更改的开始。
我该如何进行这项工作?我在forEach块中得到[ts] Element implicitly has an 'any' type because type 'MyRegistry' has no index signature.
。而且,如果无法键入此内容,如何更改将类型传递到此注册表对象中的方式,使其可以“键入”?只要最后的形状相同,就可以了。
class MyNode {
readonly name: string
constructor(name: string) {
this.name = name
}
}
class MyInterface {
readonly name: string
constructor(name: string) {
this.name = name
}
}
class MyRegistry {
constructor({ nodes, interfaces }: { nodes: MyNode[], interfaces: MyInterface[]}) {
nodes.forEach(node => {
this[node.name] = node
})
interfaces.forEach(interfaces => {
this[interfaces.name] = interfaces
})
}
}
const a = new MyNode('a')
const b = new MyNode('b')
const c = new MyNode('c')
const d = new MyInterface('d')
const e = new MyInterface('e')
const f = new MyInterface('f')
const registry = new MyRegistry({
nodes: [a, b, c],
interfaces: [d, e, f]
})
console.log(registry.a.name)
答案 0 :(得分:1)
下面的示例从仅使用{a, b, c, d, e, f}
作为注册表的想法开始,但是也保留了注册表的其他方法:
type RegistryItems = { [n: string]: MyNode | MyInterface };
class MyRegistryBase {
constructor(items: RegistryItems) {
Object.assign(this, items);
}
otherMethod() { }
}
let MyRegistry: { new <T extends RegistryItems>(items: T): MyRegistryBase & T} = <any>MyRegistryBase;
const a = new MyNode('a')
const b = new MyNode('b')
const c = new MyNode('c')
const d = new MyInterface('d')
const e = new MyInterface('e')
const f = new MyInterface('f')
const registry = new MyRegistry({a, b, c, d, e, f})
console.log(registry.a.name)
registry.otherMethod()