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

TypeScript中如何让泛型类型自动推导子对象的属性类型?

TypeScript中如何让泛型类型自动推导子对象的属性类型?

我太懂你这个痛点了——明明定义了父子对象的结构,但TypeScript就是没法自动把父字段和对应的子属性类型关联起来,导致子字段的类型检查完全失效,写什么都不报错。咱们来一步步拆解问题,找到完美的解决办法。

首先复盘下你原代码的核心问题:你把K作为SubColumn接口的顶层泛型参数,当在TableColumns里用SubColumn<Ot, keyof Ot>时,K会变成Ot所有key的联合类型;再加上你定义的ObjectType用了any,导致Ot[K]被抹平成any,最终sub.field的类型变成了keyof any(也就是string | number | symbol),自然怎么写都不会报错。

要解决这个问题,核心是让TypeScript能自动识别每个子列对应的具体父字段,从而锁定子对象的类型。这里我们可以用映射类型+联合类型的思路来实现,不用额外手动传泛型参数,完全自动推导。

修正后的完整代码

// 先把ObjectType的any改成unknown,保留类型信息(关键!)
type ObjectType = Record<string, unknown>

type Invoice = {
  docno: string
  id: number
  lines: Lines
}

type Lines = {
  item: string
  code: string
  amount: number
}

interface Column<Ot extends ObjectType> {
  field: keyof Ot
  caption: string
}

// 用映射类型遍历Ot的所有key,生成每个key对应的子列结构,再取联合类型
type SubColumn<Ot extends ObjectType> = {
  [K in keyof Ot]: {
    field: K
    // 只允许父字段对应的子类型是对象的情况加sub
    sub: Ot[K] extends ObjectType ? Column<Ot[K]> : never
  }
}[keyof Ot]

// 表格列类型是普通列或合法子列的数组
type TableColumns<Ot extends ObjectType> = (Column<Ot> | SubColumn<Ot>)[]

// 测试一下
const columns: TableColumns<Invoice> = [
  {field: 'id', caption: 'ID'},
  {field: 'lines', sub: {field: 'amount', caption: 'Amount'}}, // ✅ 完全符合类型约束
  // 下面这些写法都会触发TypeScript报错,完美!
  // {field: 'id', sub: {field: 'xxx', caption: '错误:id不是对象,不能加sub'}},
  // {field: 'lines', sub: {field: 'invalid', caption: '错误:invalid不是Lines的属性'}},
  // {field: 'nonexist', caption: '错误:nonexist不是Invoice的属性'},
]

关键思路解释

  1. 修正ObjectType的类型:把any换成unknown,这样TypeScript会保留每个子属性的原始类型,不会把所有类型都抹平成any,这是后续类型推导的基础。
  2. 用映射类型生成子列联合:SubColumn<Ot>通过[K in keyof Ot]遍历Ot的每个key,为每个key生成一个专属的子列结构(比如K='lines'时,sub必须是Column<Lines>),最后用[keyof Ot]把这些结构合并成联合类型。
  3. 自动类型推断:当你在数组里写{field: 'lines', sub: {...}}时,TypeScript会自动把这个元素匹配到联合类型中对应的K='lines'的结构,从而严格约束sub.field必须是Lines的key。

这样一来,你就不用手动指定额外的泛型参数,TypeScript会自动帮你完成父子类型的关联和检查啦!

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.07 08:49:49