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

如何为TypeScript的createProduct函数实现输入输出类型映射?

实现输入输出的类型映射

要让createProduct根据传入的具体Spec子类型返回对应的Product子类型,可以通过以下两种方式实现:

方法一:泛型结合条件类型

先定义基础类型,再通过泛型约束和条件类型建立输入到输出的映射关系:

// 定义具体的Spec子类型
type SpecA = { type: 'a'; aProp: string };
type SpecB = { type: 'b'; bProp: number };
// 区分联合类型
type Spec = SpecA | SpecB;

// 对应Product子类型
type ProductA = { type: 'a'; productAData: string };
type ProductB = { type: 'b'; productBData: number };

// 泛型函数,通过条件类型映射返回值
function createProduct<T extends Spec>(spec: T): T extends SpecA ? ProductA : ProductB {
  if (spec.type === 'a') {
    return { type: 'a', productAData: spec.aProp } as T extends SpecA ? ProductA : ProductB;
  } else {
    return { type: 'b', productBData: spec.bProp } as T extends SpecA ? ProductA : ProductB;
  }
}

// 调用示例:返回类型被推断为ProductA
const productA = createProduct({ type: 'a', aProp: 'demo' });
// 调用示例:返回类型被推断为ProductB
const productB = createProduct({ type: 'b', bProp: 123 });

这种方式利用TypeScript的条件类型,让泛型T对应传入的具体Spec子类型,进而返回匹配的Product子类型。

方法二:函数重载

通过定义函数重载签名,明确不同输入对应的输出类型:

// 定义基础类型(同方法一)
type SpecA = { type: 'a'; aProp: string };
type SpecB = { type: 'b'; bProp: number };
type Spec = SpecA | SpecB;
type ProductA = { type: 'a'; productAData: string };
type ProductB = { type: 'b'; productBData: number };

// 重载签名:明确输入输出的对应关系
function createProduct(spec: SpecA): ProductA;
function createProduct(spec: SpecB): ProductB;

// 实现签名:处理联合类型的逻辑
function createProduct(spec: Spec) {
  if (spec.type === 'a') {
    return { type: 'a', productAData: spec.aProp };
  } else {
    return { type: 'b', productBData: spec.bProp };
  }
}

// 调用示例:返回类型推断为ProductA
const productA = createProduct({ type: 'a', aProp: 'demo' });
// 调用示例:返回类型推断为ProductB
const productB = createProduct({ type: 'b', bProp: 123 });

函数重载通过多个签名声明不同的输入输出组合,TypeScript会根据传入的字面量参数匹配对应的重载,返回精确的类型。

注意事项

如果传入的是类型为Spec的变量(而非字面量),比如:

const spec: Spec = { type: 'a', aProp: 'demo' };
const product = createProduct(spec);

此时返回类型仍为ProductA | ProductB,因为变量的类型是宽泛的联合类型,TypeScript无法在编译期确定其具体子类型,这是符合预期的行为。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 05:29:55