Lit element typescript 项目全局接口声明有必要吗?
Lit element typescript project global interface declaration necessary?
Typescript Lit Element starter project 在示例元素的底部包含此全局接口声明:
declare global {
interface HTMLElementTagNameMap {
'my-element': MyElement;
}
}
有必要吗?它有什么用?
Is that necessary?
不,此声明不是您基于 LitElement 的自定义元素工作所必需的。
What is it used for?
这是 TypeScript 的一项功能,并非特定于 LitElement。
此声明有助于 TypeScript 在与 DOM API 交互时提供强类型。 JavaScript DOM API 当然不知道或不关心类型,但 TypeScript 知道。使用此机制,您可以将自定义元素的类型添加到 DOM APIs.
举个例子可能会更好地说明这一点。假设这个非常简单的自定义元素:
class HelloWorldElement extends HTMLElement {
name = 'world'; // public 'name' member with default value
// ... element internals left aside,
// just assume this.name is used somewhere ...
}
window.customElements.define('hello-world', HelloWorldElement);
现在考虑将此元素与 DOM APIs:
一起使用
const el = document.createElement('hello-world');
// el has the very generic type HTMLElement
el.name = 'custom elements'; // error! HTMLElement has no member 'name'
TypeScript 不允许。它无法(还)知道标签名称 hello-world
与 HelloWorldElement
实例一起使用,因为 customElements.define(...)
语句在运行时执行,但在编译时检查类型安全。
但是如果你扩展 HTMLElementTagNameMap
的声明,TypeScript 将知道 <hello-world></hello-world>
元素的类型:
// with the added declaration
declare global {
interface HTMLElementTagNameMap {
'hello-world': HelloWorldElement;
}
}
const el = document.createElement('hello-world');
// el has type HelloWorldElement
el.name = 'custom elements'; // OK. HelloWorldElement has a string member 'name'
如果您想了解更多详细信息,可以在 TypeScript Handbook 中找到它们。
Typescript Lit Element starter project 在示例元素的底部包含此全局接口声明:
declare global {
interface HTMLElementTagNameMap {
'my-element': MyElement;
}
}
有必要吗?它有什么用?
Is that necessary?
不,此声明不是您基于 LitElement 的自定义元素工作所必需的。
What is it used for?
这是 TypeScript 的一项功能,并非特定于 LitElement。
此声明有助于 TypeScript 在与 DOM API 交互时提供强类型。 JavaScript DOM API 当然不知道或不关心类型,但 TypeScript 知道。使用此机制,您可以将自定义元素的类型添加到 DOM APIs.
举个例子可能会更好地说明这一点。假设这个非常简单的自定义元素:
class HelloWorldElement extends HTMLElement {
name = 'world'; // public 'name' member with default value
// ... element internals left aside,
// just assume this.name is used somewhere ...
}
window.customElements.define('hello-world', HelloWorldElement);
现在考虑将此元素与 DOM APIs:
一起使用const el = document.createElement('hello-world');
// el has the very generic type HTMLElement
el.name = 'custom elements'; // error! HTMLElement has no member 'name'
TypeScript 不允许。它无法(还)知道标签名称 hello-world
与 HelloWorldElement
实例一起使用,因为 customElements.define(...)
语句在运行时执行,但在编译时检查类型安全。
但是如果你扩展 HTMLElementTagNameMap
的声明,TypeScript 将知道 <hello-world></hello-world>
元素的类型:
// with the added declaration
declare global {
interface HTMLElementTagNameMap {
'hello-world': HelloWorldElement;
}
}
const el = document.createElement('hello-world');
// el has type HelloWorldElement
el.name = 'custom elements'; // OK. HelloWorldElement has a string member 'name'
如果您想了解更多详细信息,可以在 TypeScript Handbook 中找到它们。