打字稿:用开始标签和一些字符串内容定义 html 的模板文字

Typescript: Template Literal to define html with opening tags and some string content

我想创建一个类型来确保字符串以 html 标签开头并以 结束 。 目前我没有得到匹配的开始和结束标签。我可以使用一些推断或其他 Typescript 魔法吗?

type Template<
    TAG extends string,
    CONTENT extends string,
    ATTRIBUTES extends string
> = `<${TAG}${ATTRIBUTES}>${CONTENT}</${TAG}>`;

export type HtmlTemplate<HTML extends string> = Template<`${keyof HTMLElementTagNameMap}`, HTML, ` ${string}`>;

export type UliConfigTemplate = `${StyleConfig<string>} ${TemplateConfig<string>}`;

当前版本基本上产生了以下类型定义(看标签不匹配):

type TemplateConfig<HTML extends string> = `<object ${string}>${HTML}</object>` | `<object ${string}>${HTML}</a>` | `<object ${string}>${HTML}</abbr>` | `<object ${string}>${HTML}</address>` | `<object ${string}>${HTML}</applet>` | `<object ${string}>${HTML}</area>` | `<object ${string}>${HTML}</article>` | `<object ${string}>${HTML}</aside>` | `<object ${string}>${HTML}</audio>` | ... 14151 more ... | `<wbr ${string}>${HTML}</wbr>````

你可以的。 TAG 在您的示例中键入一个联合,如 'object' | 'a' | 'abbr' | ...。您需要的是将此联合的每个成员“映射”到它自己的模板文字,然后获取所有这些映射的模板文字的联合。可以这样做:

type Template<
  TTag extends string,
  TContent extends string,
  TAttributes extends string,
> = {
  // mapping every tag to its own template literal
  [tag in TTag]: `<${tag}${TAttributes}>${TContent}</${tag}>`
}[TTag]

export type HtmlTemplate<HTML extends string> = Template<
  keyof HTMLElementTagNameMap, 
  HTML, 
  ` ${string}`
>;

现在它有类型

`<object ${string}>${HTML}</object>` | `<a ${string}>${HTML}</a>` 
| `<abbr ${string}>${HTML}</abbr>` | `<address ${string}>${HTML}</address>` 
| `<area ${string}>${HTML}</area>` | `<article ${string}>${HTML}</article>` 
| `<aside ${string}>${HTML}</aside>` | `<audio ${string}>${HTML}</audio>` | `<b ${string}>${HTML}</b>` 
| ... 107 more ... | `<wbr ${string}>${HTML}</wbr>`

Playground link