You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在TypeScript泛型数组中对单个元素取keyof并做独立类型校验

解决方案

首先你需要调整泛型的作用域,把每个映射项的目标类型校验下放到单个项的维度,而不是在函数全局声明固定的目标类型,具体实现如下:

  1. 首先重命名映射类型,避免和JS内置Map类型冲突:
type Table<ExtT> = {
  id: number
  name: string
} & ExtT

// 重命名避免和原生Map冲突
type TableMap<SourceT, TargetT> = {
  name: string,
  map: {
    from: keyof SourceT,
    to: keyof TargetT
  }
}
  1. 新增一个柯里化的辅助构造函数,先绑定统一的源类型(也就是你例子里的tC),再给每个单独的映射项指定不同的目标类型,在创建阶段就完成类型校验:
// 第一步传入源类型,返回绑定了源类型的构造函数
const createTableMap = <SourceT extends object>() => {
  return <TargetT extends object>(mapItem: TableMap<SourceT, TargetT>) => mapItem
}
  1. 调整doSomething的类型定义,仅约束统一的源类型即可:
const doSomething = <SourceT extends object>(maps: TableMap<SourceT, any>[]) => {
  // 你的业务逻辑
}

用法示例

先提前定义好你的业务类型:

// 示例业务类型
type tA = Table<{prop1: string, prop2: string}>
type tB = Table<{foo: string, bar: string}>
type tC = Table<{cProp1: string, cProp2: string}>

调用时先绑定源类型,再创建每个映射项即可实现你要的校验效果:

// 先绑定本次调用统一的源类型为tC
const createTfMap = createTableMap<tC>()

doSomething([
  createTfMap<tB>({
    name: 'map1',
    map: {
      from: 'cProp1', // 校验通过:cProp1是tC的属性
      to: 'foo' // 校验通过:foo是tB的属性
    }
  }),
  createTfMap<tA>({
    name: 'map1',
    map: {
      from: 'cProp1',
      to: 'bar' // 校验失败:bar不是tA的属性,符合预期
    }
  })
])

原代码问题说明

你之前的写法里把S泛型声明在了doSomething的顶级,意味着整个数组所有映射项的目标类型S必须是同一个,没法支持每个项用不同的目标类型做校验。把泛型下放到单个映射项的创建环节后,就能实现每个项独立校验的需求。


内容的提问来源于stack exchange,提问作者Gopikrishna S

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 00:15:02