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

如何基于枚举与ORM类模型实现TypeScript类型推断

TypeScript 类型推断问题:继承场景下ORM类型映射异常

需求说明

定义枚举 DataType { NUMBER, STRING } 及对象 const example: Record<string, DataType> = { id: DataType.NUMBER, name: DataType.STRING },希望通过泛型 converter() 函数实现类型推断,让 TypeScript 将 example.id 识别为 number(而非 DataType.NUMBER)、example.name 识别为 string(而非 DataType.STRING),仅需实现类型逻辑,无需函数具体代码。

最终目标是实现类似 ORM 的效果:用户传入数据模型(schema),函数返回与模型字段对应的原生类型对象,示例如下:

class Model {
    public get(... columns: string[]) {
        // ...
    }
}

class User extends Model {
    public columns: {
        id: DataType.NUMBER,
        name: DataType.STRING,
        age: DataType.NUMBER
    }
}

const user = new User().get("id", "name")

// 期望 typeof user 等价于 { id: number, name: string }

简单场景的可行实现

在非继承的简单场景下,已实现对应的类型转换逻辑,代码如下:

function convert<T extends Record<string, DataType>>(schema: T) {
     return {} as { [K in keyof T]: T[K] extends DataType.NUMBER ? number : T[K] extends DataType.STRING ? string : never };
}

继承场景下的问题

但在类继承的复杂场景中,类型推断出现异常:data.id 和 data.name 被推断为 never,而非预期的 number 和 string,相关代码如下:

interface Schema {
  [k: string]: DataType
}

type SchemaReturn<S extends Schema, C extends keyof S> = {
    [K in C]: S[K] extends DataType.NUMBER ? number : S[K] extends DataType.STRING ? string : never;
};

abstract class Model {
  public schema: Schema = {};
  
  public select<C extends keyof this["schema"]>(... columns: C[]) {
    return {} as SchemaReturn<typeof this["schema"], C>;
  }
}

class User extends Model {
  public schema = {
    id: DataType.NUMBER,
    name: DataType.STRING,
    age: DataType.NUMBER
  }
}

const user = new User;
const data = user.select("id", "name");

data.id; // 预期为 number,实际推断为 never
data.name; // 预期为 string,实际推断为 never

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 13:50:16