Skip to content

TypeScript 动态参数返回类型实现

为了实现动态根据参数生成返回类型,需要使用 TypeScript 的 const 泛型参数和映射类型。以下是解决方案:

typescript
const zzz = <const T extends readonly { name: PropertyKey }[]>(
  arr: T
): { [K in T[number]['name']]: string } => {
  return arr.reduce((acc, item) => {
    acc[item.name] = ''
    return acc
  }, {} as any)
}

// 使用示例
const answers = zzz([{ name: 'aa' }, { name: 'bb' }])
// answers 类型为 { aa: string; bb: string }

关键点解析:

  1. const 泛型参数 (<const T>)

    • 使 TypeScript 将传入的数组推断为字面量类型
    • 保留数组元素中 name 属性的具体字面量类型(如 'aa' 而不是 string)
  2. 类型约束 (readonly { name: PropertyKey }[])

    • 确保传入的是只读数组(保持类型推断稳定性)
    • PropertyKey 保证 name 属性可作为对象键(string | number | symbol)
  3. 映射类型 ({ [K in T[number]["name"]]: string })

    • T[number] 获取数组元素类型的联合
    • T[number]["name"] 提取所有元素的 name 属性值的联合类型
    • 用这些字面量值作为新对象的键,值类型为 string

注意事项:

  • 需要 TypeScript 4.9+ 支持 const 泛型参数
  • 实际实现需要使用类型断言(as any),因为 TypeScript 无法在 reduce 过程中验证动态键
  • 重复的 name 会导致后续值覆盖前面的,但类型系统不会报错(需业务逻辑自行处理)

最终效果:当传入 [{ name: 'aa' }, { name: 'bb' }] 时,自动推导返回类型为 { aa: string; bb: string }

Released under the MIT License.