TypeScript能否动态定义类型?如何基于服务端返回数组生成带类型提示的对象
实现方案
运行时生成目标对象
直接用数组的reduce方法即可完成转换,不需要提前知晓数组元素内容,示例代码如下:
// 假设从服务端拿到的尺寸数组为sizeArr const sizeArr = await fetch('/your/api/path').then(res => res.json()) const sizeMap = sizeArr.reduce((accumulator, current) => { accumulator[current] = current return accumulator }, {})
转换完成后你就可以直接通过属性名访问对应值,例如sizeMap.small、sizeMap['1080p']。
TypeScript动态类型适配
如果你使用TypeScript需要获得类型提示,可以通过泛型映射实现动态类型:
- 如果请求前可以枚举所有可能的返回值,直接用字面量联合类型断言即可获得完整类型提示:
function generateMap<T extends string>(arr: T[]): { [K in T]: K } { return arr.reduce((acc, cur) => { acc[cur] = cur return acc }, {} as { [K in T]: K }) } // 调用时断言数组类型为可能的字面量联合 const sizeMap = generateMap(sizeArr as ('small' | 'medium' | 'large' | '2k' | '4k')[]) // 后续访问sizeMap时TS会自动提示所有合法属性名
- 如果完全无法预知返回值范围,可以用索引签名定义类型避免报错:
const sizeMap = sizeArr.reduce((acc, cur) => { acc[cur] = cur return acc }, {} as Record<string, string>)
替代方案
如果你的需求只是判断某个尺寸是否可用、不需要直接取属性值,用Set实现会更简洁:
const sizeSet = new Set(sizeArr) // 校验尺寸是否可用 console.log(sizeSet.has('small')) // 返回true/false
Set的存在性判断时间复杂度为O(1),性能优于数组遍历。
内容的提问来源于stack exchange,提问作者nonamenoname
相关产品推荐
相关产品推荐

