TypeScript如何自动生成IElements所有标签的IAttributes联合类型?
如何自动生成基于IElements的Box组件Props联合类型?
我正在构建一个支持is属性的Box组件,通过is属性指定渲染的HTML元素,示例代码如下:
<Box is="a" href="..."> ... </Box>
为实现类型支持,我定义了存储标准元素及其属性的IElements接口:
interface IElements { a: { href: string; /* 其他属性 */ }; button: { /* button相关属性 */ }; // 外部库提供的其他元素... }
接着创建了工具类型IAttributes,生成包含is: TAG与对应元素属性的交叉类型:
type IAttributes<K extends keyof IElements> = { is: K; } & IElements[K]; const attributes: IAttributes<"a"> = { is: "a", href: "..." };
目前我手动定义了Box组件的Props类型为各标签的IAttributes联合类型:
type IProps = IAttributes<"a"> | IAttributes<"button">;
但IElements来自外部库,标签会随版本增减,请问能否让TypeScript自动遍历IElements的所有HTML标签,动态生成IProps的联合类型,而非手动枚举所有标签?
当然可以,利用TypeScript的映射类型和索引访问类型就能实现动态生成联合类型,不需要手动枚举:
方案一:分步实现
// 先创建映射类型,遍历IElements所有键生成对应的IAttributes类型 type IAttributesMap = { [K in keyof IElements]: IAttributes<K>; }; // 提取映射类型中所有值的联合类型 type IProps = IAttributesMap[keyof IAttributesMap];
方案二:简化为单行
如果觉得分步写麻烦,也可以直接合并成一行:
type IProps = { [K in keyof IElements]: { is: K } & IElements[K] }[keyof IElements];
原理说明
这个写法会自动遍历IElements的所有键(即所有标签名),为每个键生成对应的{ is: K } & IElements[K]交叉类型,最后通过[keyof IElements]把映射类型里的所有值提取出来,组成完整的联合类型。后续外部库更新IElements的标签列表时,IProps会自动同步更新,完全不需要手动修改代码。
内容的提问来源于stack exchange,提问作者hafes92059
相关产品推荐
相关产品推荐

