【发布时间】:2020-10-07 02:49:16
【问题描述】:
总之
如何在 TypeScript 中声明:在这个类中,任何以“$”开头的属性都是对元素的引用?
上下文
我有一个自定义元素类方法,它自动将任何具有data-reference 属性的子元素存储在一个属性中,该属性以它的值命名,前缀为'$'。
它在 vanilla JavaScript 中完美运行:
class SomeComponent extends HTMLElement {
connectedCallback() {
this.setReferences()
console.log(this.$myRef) // <div data-reference="myRef"></div>
}
setReferences() {
const referencedElements = this.querySelectorAll('[data-reference]')
referencedElements.forEach((element) => {
const referenceName = '$' + element.getAttribute('data-reference')
this[referenceName] = element
})
}
}
customElements.define('some-component', SomeComponent)
<some-component>
<div data-reference="myRef"></div>
</some-component>
但这不会在 TypeScript 中编译,谁不知道 $myRef 属性:
console.log(this.$myRef) // Property '$myRef' does not exist on type 'SomeComponent'
^^^^^^
到目前为止,我已经提出了 3 个解决方法,但没有一个是完全令人满意的。
1。类型断言
不!
console.log((this as any).$myRef) // <div data-reference="myRef"></div>
关键是提供对任何$ref 的快速访问,因此添加as any 或<any>(加上括号)不是一个可行的解决方案。
2。对象字面量
可能是最干净的,但不完全是我想要实现的。
type ElementReferenceMap = { [key: string]: Element }
class SomeComponent extends HTMLElement {
ref: ElementReferenceMap = {};
setReferences() {
const referencedElements = this.querySelectorAll('[data-reference]');
referencedElements.forEach((element) => {
const referenceName = element.getAttribute('data-reference');
this.ref[referenceName] = element as Element;
})
console.log(this.ref.myRef); // <div data-reference="myRef"></div>
}
}
通过将其重命名为 this.$.myRef 我更接近了,但它仍然不等同于原生 JavaScript 版本。
3。索引属性
按预期工作(如 JavaScript 版本),但感觉不对,因为它允许任何属性值。
class SomeComponent extends HTMLElement {
// [x: string]: Element; // conflict with other properties
[x: string]: any; // ok
setReferences() {
const referencedElements = this.querySelectorAll('[data-reference]');
referencedElements.forEach((element) => {
const referenceName = '$' + element.getAttribute('data-reference');
this[referenceName] = element;
})
console.log(this.$myRef); // <div data-reference="myRef"></div>
}
}
我可能缺少明显的解决方案,因为我对 TypeScript 很陌生。 提前致谢!
【问题讨论】:
-
第二个选项是要走的路。 “任何以 '$' 开头的属性”的问题 - 无法真正验证
标签: typescript computed-properties type-declaration