【发布时间】:2020-06-25 10:48:54
【问题描述】:
以这段代码为例:
const [divEl, spanEl] = createElements([
['div', { id: 'test' }, [
['a', { href: 'test' }, [
['img', { src: 'test' }, null]
]],
['img', { href: 'test' }, null]
]],
['span', null, null]
]);
我希望 TypeScript 推断 divEl 的类型为 HTMLDivElement 和 spanEl 的类型为 HTMLSpanElement。而且我还希望它检查给定的属性并根据推断的类型显示错误(例如,它应该在['img', { href: 'test' }, null] 上显示错误,因为HTMLImageElement 没有href 属性)。
经过一番研究,这是我目前所拥有的:
type ElementTag = keyof HTMLElementTagNameMap;
type ElementAttributes<T extends ElementTag> = {
[K in keyof HTMLElementTagNameMap[T]]?: Partial<HTMLElementTagNameMap[T][K]> | null;
};
type ElementArray<T extends ElementTag> = [
T,
ElementAttributes<T> | null,
ElementArray<ElementTag>[] | string | null
];
type MappedElementArray<T> = {
[K in keyof T]: T[K] extends ElementArray<infer L> ? HTMLElementTagNameMap[L] : never;
};
// This is the signature for the createElements function.
type CreateElements = <T extends ElementArray<ElementTag>[] | []>(
array: T
) => MappedElementArray<T>;
我必须将 ElementArray<ElementTag>[] 更改为通用名称,但我不确定如何继续。
这可能吗?
我知道可以手动完成,但 T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, ... 并不漂亮。
【问题讨论】:
-
这听起来可能需要 Variadric Tuples 在 Typescript 4.0 中发布。
-
有趣。我还没有想出如何将它应用于这个问题,但是谢谢,我会花一些时间来解决这个问题。
标签: typescript