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

TypeScript泛型实现多返回类型的类型安全问题

解决Typegoose多租户多模型的类型推导问题

问题核心

你当前的getModelsForDbWithKey方法无法生成正确的类型提示,原因是缺少针对Schema到模型类型的泛型映射约束,无法让TypeScript自动推导返回值的具体类型。

解决方案

通过定义泛型映射类型和泛型约束,让方法根据传入的Schema键值对,自动推导对应模型的类型。以下是改造后的完整实现:

1. 基础类型定义

先创建一个泛型类型,用于将Typegoose的Schema类映射为对应的模型类型:

import { getModelForClass, ReturnModelType } from '@typegoose/typegoose';
import mongoose from 'mongoose';

// 泛型类型:把Schema类映射为Typegoose模型类型
type SchemaToModel<T> = {
  [K in keyof T]: ReturnModelType<T[K]>;
};

2. 改造多模型获取方法

给方法添加泛型约束,让它接收Schema键值对并返回对应类型的模型集合:

// 租户数据库切换逻辑(假设你已有此实现)
function getTenantDb(tenantId: string): mongoose.Connection {
  return mongoose.connection.useDb(`tenant_${tenantId}`);
}

// 单个模型获取方法(保留原有逻辑,已支持类型提示)
function getModelForDb<T>(clazz: new () => T, tenantId: string): ReturnModelType<typeof clazz> {
  const db = getTenantDb(tenantId);
  return getModelForClass(clazz, { existingConnection: db });
}

// 改造后的多模型方法,自动推导类型
function getModelsForDbWithKey<T extends Record<string, new () => any>>(
  schemas: T,
  tenantId: string
): SchemaToModel<T> {
  const db = getTenantDb(tenantId);
  const models: Partial<SchemaToModel<T>> = {};

  for (const key in schemas) {
    if (schemas.hasOwnProperty(key)) {
      models[key] = getModelForClass(schemas[key], { existingConnection: db });
    }
  }

  return models as SchemaToModel<T>;
}

3. 使用示例

现在调用getModelsForDbWithKey时,每个模型都会自动获得完整的类型提示:

// 定义你的Schema类
class User {
  name!: string;
  email!: string;
}

class Order {
  userId!: string;
  amount!: number;
}

// 获取多模型,TypeScript自动推导类型
const tenantModels = getModelsForDbWithKey({ User, Order }, 'tenant_123');

// 此时tenantModels.User和tenantModels.Order都有完整的智能提示
tenantModels.User.findOne({ name: 'Alice' }); // 类型校验生效
tenantModels.Order.create({ userId: '1', amount: 99 }); // 参数类型自动提示

关键说明

  • 泛型映射:SchemaToModel<T>遍历传入的Schema对象的每个键,将Class类型转换为Typegoose的ReturnModelType,确保返回值类型与输入Schema一一对应。
  • 泛型约束:T extends Record<string, new () => any>确保传入的schemas是合法的Schema类集合。
  • 类型断言:方法内部的as SchemaToModel<T>是因为TypeScript无法自动推断循环赋值后的完整类型,手动断言仅用于类型推导,不影响运行时逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 00:18:22