繁体   English   中英

如何在 TypeScript 中获取 Literal 而不是 Union 类型

[英]How to get Literal instead of Union type in TypeScript

我创建了一个用于创建动态元素的函数。 但不是返回元素的文字类型,而是返回<HTMLElementTagNameMap>的并集。

function createElement(type: keyof HTMLElementTagNameMap) {
  return document.createElement(type)
}

如果我们只使用上面的函数,它会返回以下的联合:

(HTMLElement | HTMLObjectElement | HTMLAnchorElement | HTMLAreaElement | HTMLAudioElement | ... 57 more ... | HTMLVideoElement).

到目前为止我尝试了什么:

type valueOf<T> = T[keyof T]

function createElement<T extends valueOf<HTMLElementTagNameMap>>(type: keyof HTMLElementTagNameMap) {
  return document.createElement(type) as T
}

PS - 我也很困惑? 上述功能是如何工作的?

而是以如下所述的方式使用上述功能:

const div = createElement<HTMLDivElement>('div')

我希望它像我们使用时一样自动推断类型的type

let li = document.createElement('li')

该代码有效,因为您通过泛型类型T手动传递返回类型。

您可以通过以下代码将其自动化:

const createElement = <K extends keyof HTMLElementTagNameMap>(name: K): HTMLElementTagNameMap[K]{
  return document.createElement(name)
}

const div = createElement('div')
console.log(div)
// [LOG]: HTMLDivElement: {} 

它和你写的没有什么不同。 我希望它有所帮助。 如果您有任何问题,欢迎在评论中提问

如果您想要与document.createElement相同的行为,您可以简单地编写

function createElement<K extends keyof HTMLElementTagNameMap>(type: K) {
  return document.createElement(type);
}

或者如果你想通过 HTML 元素选择标签名称,你可以使用这样的东西

type PickTagNameForHTMLElement<TargetElement> = {
  [K in keyof HTMLElementTagNameMap]: HTMLElementTagNameMap[K] extends TargetElement ? K : never;
}[keyof HTMLElementTagNameMap];

function createElement<TargetElement extends HTMLElement>(type: PickTagNameForHTMLElement<TargetElement>) {
  return document.createElement(type);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM