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

如何构建TypeScript接口实现基于模型对象的类型约束

解决TypeScript中Command接口的类型约束问题

最终实现方案

通过映射类型生成联合类型,自动生成所有合法的table与attribute对应组合,无需手动传入泛型参数,同时严格约束类型匹配:

interface ModelA {
  label: string
}
interface ModelB {
  name: string
}

interface Models {
  A: ModelA
  B: ModelB
}

// 遍历Models的所有键,生成对应的合法Command类型,再合并为联合类型
type Command = {
  [K in keyof Models]: {
    table: K
    attribute: keyof Models[K]
  }
}[keyof Models]

// 直接使用即可,类型约束完全生效
const commands: Command[] = [
  { table: 'A', attribute: 'label' }, // 合法
  { table: 'B', attribute: 'name' }, // 合法
  // 以下代码会触发类型错误,符合预期
  // { table: 'A', attribute: 'name' },
  // { table: 'C', attribute: 'xxx' },
]

为什么之前的方案行不通?

  1. 泛型必须传参的问题:
    最初的Command<Model extends keyof Models>需要手动指定泛型参数,用Command<any>会完全失去类型约束,违背需求。

  2. 泛型默认值的问题:
    当给泛型设置默认值Model = keyof Models时,TypeScript会将Model视为联合类型'A' | 'B',此时Models[Model]是ModelA | ModelB,但TypeScript无法在单个接口中关联table和attribute的对应关系——它无法判断当前table是'A'还是'B',因此无法约束attribute必须匹配对应模型的属性,甚至会抛出索引类型错误。

可选:保留泛型版本(用于指定具体Model的场景)

如果需要单独创建指定某类Model的Command,可以同时保留泛型接口,再基于它生成联合类型:

// 泛型接口,用于单个指定Model的场景
interface CommandGeneric<Model extends keyof Models> {
  table: Model
  attribute: keyof Models[Model]
}

// 自动生成所有合法组合的联合类型
type Command = CommandGeneric<keyof Models>[keyof Models]

// 单个指定Model的用法
const aCommand: CommandGeneric<'A'> = { table: 'A', attribute: 'label' }

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 13:05:19