TypeScript如何从对象数组的role字段动态生成字符串字面量联合类型
实现方案
可以动态实现,只需要调整原有代码的类型定义方式即可,核心是保留数组元素中role字段的字面量类型不被TS自动拓宽。
具体实现代码
interface IPeople { id: number, role: string } // 去掉显式的IPeople[]类型注解,改用satisfies做类型校验,同时加as const保留字面量类型 const peoples = [ { id: 1, role: 'student' }, { id: 2, role: 'teacher' } ] as const satisfies IPeople[]; // 直接提取联合类型 type PeoplesRoles = typeof peoples[number]['role']; // 此时PeoplesRoles的类型等价于:'student' | 'teacher'
原理解释
as const会将数组和内部对象标记为只读常量,让TS不会把id、role的类型拓宽为通用的number、string,保留具体的字面量值作为类型satisfies IPeople[]用来校验数组格式完全符合IPeople接口的要求,不会丢失类型校验能力,替代原来直接写的IPeople[]类型注解(直接写会丢失字面量信息)typeof peoples[number]['role']的推导逻辑:- 先通过
typeof peoples拿到数组的TS类型 - 用
[number]遍历数组所有元素,得到所有元素类型的联合 - 最后用
['role']提取每个元素的role属性类型,最终得到所有role字面量的联合类型
- 先通过
注意事项
TS的类型都是编译时静态生成的,如果你需要在运行时动态修改peoples数组的内容,新增/删除不同role的元素,是没法动态同步更新PeoplesRoles类型的,这种场景只能手动维护联合类型,或者用编译前的代码扫描工具生成类型。
内容的提问来源于stack exchange,提问作者kofyohugna
相关产品推荐
相关产品推荐

