如何用TypeScript泛型条件类型精简React组件动态属性校验实现
精简实现方案
直接通过带默认值的泛型即可实现所有场景的类型校验,砍掉了所有冗余的联合类型定义:
function Component< TId extends string = 'id', TName extends string = 'name' >({ idIdentifier = 'id' as TId, nameIdentifier = 'name' as TName, persons }: { idIdentifier?: TId nameIdentifier?: TName persons: Array<Record<TId, string> & Record<TName, string>> }) { // 组件渲染逻辑 }
实现说明
- 给两个泛型参数设置了默认字面量类型
'id'和'name',无需额外定义多分支联合类型,即可自动覆盖所有四个场景的类型推导:
- 不传两个标识符参数时,泛型用默认值,
persons要求必须有id和name字段 - 仅传自定义
idIdentifier时,TS自动推导TId为传入的字符串字面量,TName用默认值,persons要求匹配对应字段 - 仅传自定义
nameIdentifier时逻辑同上 - 两个自定义标识符都传时,TS自动推导两个泛型的字面量类型,
persons要求匹配两个自定义字段
- 默认值后的
as TId/as TName断言是为了避免TS将默认值的类型拓宽为string,保留字面量类型保证推导正确。
校验效果完全匹配要求
(注:你的使用示例中options为笔误,实际对应props为persons)
<Component persons={[{ id: "1", name: "Joe" }]} />// 校验通过<Component persons={[{ id: "1", nickName: "Joe" }]} />// 类型报错,缺少name字段<Component nameIdentifier="nickName" persons={[{ id: "1", nickName: "Joe" }]} />// 校验通过<Component nameIdentifier="nickName" persons={[{ id: "1", name: "Joe" }]} />// 类型报错,缺少nickName字段<Component nameIdentifier="nickName" idIdentifier="value" persons={[{ id: "1", nickName: "Joe" }]} />// 类型报错,缺少value字段<Component nameIdentifier="nickName" idIdentifier="value" persons={[{ value: "1", nickName: "Joe" }]} />// 校验通过
内容的提问来源于stack exchange,提问作者Darryl Edwards
相关产品推荐
相关产品推荐

