typescript - 是否可以根据输入在注册表类上键入动态属性?
问题描述
我正在尝试将注册表对象移植到打字稿。它具有基于传入对象的属性的动态命名属性。我现在可能不会这样设计它,但是有大量代码库按原样使用它,并且围绕它获得一个好的类型定义是改变它的开始。
我怎样才能使这项工作?我进入[ts] Element implicitly has an 'any' type because type 'MyRegistry' has no index signature.
了 forEach 块。如果无法输入此内容,我该如何更改将类型传递到此注册表对象的方式以使其“可输入”?只要最后的形状是一样的,我们就可以了。
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)
解决方案
以下示例从仅用{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()
推荐阅读
- typescript - 使用 graphql 抑制声明预期的 ts(1146)
- java - 如何更改实时数据库中的特定字段
- python - Python SQL fetchall() 不返回任何内容
- regex - htaccess 用问号完整 url 重写
- lua - 为 WoW (Lua) 制作文本框架
- discord - 卡尔机器人中的硬自定义标签(不和谐)
- javascript - Electron webContents 无法注册监听器
- python - ValueError: 层序贯_1 的输入 0 与层不兼容: : 预期 min_ndim=4,发现 ndim=2。收到的完整形状:(32768, 1)
- javascript - 尝试在 discord.js 中写入 `message.channel.send(embed)` 时出现错误,并说无法读取已发送
- ios - 用于完成按钮的文本字段的 swift ui 扩展