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

如何实现可指定填充属性的TypeScript User泛型类型?

实现支持部分填充属性的泛型User类型

首先给出基础接口定义:

interface Tenant {
  id: number;
  name: string;
}

interface Server {
  id: number;
  location: string;
  ip: string;
}

需求说明

需要定义泛型User类型,满足:

  • 默认状态下tenant和server属性类型为number(未填充)
  • 可单独指定某一个或多个属性填充为对应对象类型,支持以下用法:
    • User:tenant和server均为number
    • User<{ tenant: Tenant }>:tenant为Tenant,server仍为number
    • User<{ tenant: Tenant; server: Server }>:两者均为对应对象类型

原有方案的问题

之前的实现通过强制泛型参数继承包含两个属性的UserPopulate接口,导致必须同时指定tenant和server或都不指定,无法单独配置部分填充属性。

可行实现方案

方案一:基于Partial泛型与条件类型

通过可选属性的泛型参数结合条件类型推导实现灵活的部分填充:

type User<Populate extends Partial<{ tenant: Tenant; server: Server }> = {}> = {
  id: number;
  name: string;
  tenant: Populate extends { tenant: infer T } ? T : number;
  server: Populate extends { server: infer T } ? T : number;
};

方案说明

  1. 泛型参数Populate使用Partial包裹,允许只传入部分属性(空对象对应默认未填充状态)
  2. 利用条件类型判断:若Populate包含目标属性,则取其指定类型;否则默认使用number

使用示例

// 默认情况:tenant和server均为number
const user: User = { id: 1, name: "张三", tenant: 1001, server: 2001 };

// 仅填充tenant为Tenant类型
const user2: User<{ tenant: Tenant }> = {
  id: 2,
  name: "李四",
  tenant: { id: 1001, name: "租户A" },
  server: 2001
};

// 同时填充tenant和server为对应对象类型
const user3: User<{ tenant: Tenant; server: Server }> = {
  id: 3,
  name: "王五",
  tenant: { id: 1001, name: "租户A" },
  server: { id: 2001, location: "北京", ip: "192.168.1.1" }
};

方案二:基于属性名联合类型

这种写法通过指定要填充的属性名联合类型实现,语义更直观:

type UserPopulateOptions = { tenant: Tenant; server: Server };
type User<Populate extends keyof UserPopulateOptions = never> = {
  id: number;
  name: string;
} & {
  [K in keyof UserPopulateOptions]: K extends Populate ? UserPopulateOptions[K] : number;
};

使用示例

// 默认情况:tenant和server均为number
const user: User = { id: 1, name: "张三", tenant: 1001, server: 2001 };

// 仅填充tenant
const user2: User<'tenant'> = {
  id: 2,
  name: "李四",
  tenant: { id: 1001, name: "租户A" },
  server: 2001
};

// 同时填充tenant和server
const user3: User<'tenant' | 'server'> = {
  id: 3,
  name: "王五",
  tenant: { id: 1001, name: "租户A" },
  server: { id: 2001, location: "北京", ip: "192.168.1.1" }
};

你可以根据业务场景的语义偏好选择合适的方案。

内容的提问来源于stack exchange,提问作者Arūnas Smaliukas

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 17:25:49