打字稿:用开始标签和一些字符串内容定义 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>`
我想创建一个类型来确保字符串以 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>`