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

TypeScript中如何在另一类型中使用父类型的值?(ORM场景)

问题描述

我正在尝试编写一个简易ORM,代码如下:

type Models = {
   User: {
      name: string
   },
   Template: {
      text: string
   }
}

type ExtractKeysFrom<T> = keyof T

type ModelsKeys = ExtractKeysFrom<Models, Object>
// 正确返回:'User' | 'Template'

type ORM = {
   model: (modelName: ModelsKeys) => {
      create(props: Models[typeof modelName]): Promise<boolean>
   }
}

实现代码:

declare const orm: () => ORM;
orm().model('User').create({
  name: 'Adam'
})

我希望create()中的props能自动匹配对应模型(比如User)的属性,但当前得到的是:

create(props: User | Template): Promise<boolean>

我知道typeof modelName的写法有误,应该用extends进行类型检查,但不清楚具体实现方式,能否提供建议?

解决方案

问题核心是model方法没有通过泛型建立传入参数与返回值的类型关联,导致TypeScript无法精准推导create的参数类型。你需要将model定义为泛型方法,用泛型约束绑定模型名和对应的数据结构。

修改后的类型定义如下:

type Models = {
   User: {
      name: string
   },
   Template: {
      text: string
   }
}

// 简化类型定义,直接用keyof Models获取模型键集合
type ModelsKeys = keyof Models;

type ORM = {
   // 泛型K约束为Models的键类型
   model<K extends ModelsKeys>(modelName: K): {
      // 通过K索引Models,精准获取对应模型的属性类型
      create(props: Models[K]): Promise<boolean>
   }
}

修改后,调用orm().model('User').create(...)时,TypeScript会自动推导props必须符合User的结构;调用model('Template')时,props则会匹配Template的类型,不会再出现联合类型的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 15:18:27