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

TypeScript中基础类型扩展可选类型的优化实现问询

问题描述

我定义了如下基础类型:

type BaseProps = {
  foo: boolean;
  bar?: string;
};

该基础类型可扩展以下两种额外类型:

type WithOkButton = {
  useOkButton: boolean;
  onOK(): void;
};

type WithCancelButton = {
  useCancelButton: boolean;
  onCancel(): void;
}

我的目标是得到一个包含BaseProps以及上述额外类型所有组合的类型,组合情况包括:

  • 不包含任何额外类型
  • 同时包含两种额外类型
  • 仅包含WithOkButton
  • 仅包含WithCancelButton

我可以通过以下方式实现需求,但写法过于繁琐,能否提供更优的实现方案?

type BaseWithOK = BaseProps & WithOkButton;

type BaseWithCancel = BaseProps & WithCancelButton;

type BaseWithBoth = BaseProps & WithOkButton & WithCancelButton;

type ResultType = BaseProps | BaseWithOK | BaseWithCancel | BaseWithBoth;

补充说明

若需要支持三种按钮的所有组合,代码会变为如下形式,写法复杂度进一步提升:

type BaseProps = {
  foo: boolean;
  bar?: string;
};

type A = {
  useA: boolean;
  onClickA(): void;
};

type B = {
  useB: boolean;
  onClickB(): void;
};

type C = {
  useC: boolean;
  onClickC(): void;
};

type BasePropsWithA = A & BaseProps
type BasePropsWithB = B & BaseProps
type BasePropsWithC = C & BaseProps
type BasePropsWithAB = A & B & BaseProps
type BasePropsWithBC = B & C & BaseProps
type BasePropsWithAC = A & C & BaseProps
type BasePropsWithABC = A & B & C & BaseProps

type Props = BaseProps | BasePropsWithA | BasePropsWithB | BasePropsWithC
| BasePropsWithAB | BasePropsWithBC | BasePropsWithAC | BasePropsWithABC;

优化方案

可以通过泛型工具类型自动生成所有扩展组合,无需手动枚举每种情况,扩展性极强,新增扩展类型只需修改一处代码。

核心思路

  1. 定义工具类型AllCombinations,递归遍历扩展类型的联合,生成所有可能的子集交集(单个扩展类型、多个扩展类型的组合)。
  2. 加上空集{}覆盖“不包含任何扩展类型”的情况。
  3. 最终将基础类型与所有扩展组合交叉,得到目标类型。

代码实现(两种扩展类型场景)

type BaseProps = {
  foo: boolean;
  bar?: string;
};

type WithOkButton = {
  useOkButton: boolean;
  onOK(): void;
};

type WithCancelButton = {
  useCancelButton: boolean;
  onCancel(): void;
};

// 生成联合类型的所有子集组合(单个/多个扩展类型的交集)
type AllCombinations<U> = U extends infer T ? T | (T & AllCombinations<Exclude<U, T>>) : never;
// 包含空集的所有扩展组合
type AllPossibleExtensions = {} | AllCombinations<WithOkButton | WithCancelButton>;

// 最终目标类型
type ResultType = BaseProps & AllPossibleExtensions;

代码实现(三种扩展类型场景)

仅需修改扩展类型的联合参数,其余代码完全复用:

type BaseProps = {
  foo: boolean;
  bar?: string;
};

type A = {
  useA: boolean;
  onClickA(): void;
};

type B = {
  useB: boolean;
  onClickB(): void;
};

type C = {
  useC: boolean;
  onClickC(): void;
};

type AllCombinations<U> = U extends infer T ? T | (T & AllCombinations<Exclude<U, T>>) : never;
type AllPossibleExtensions = {} | AllCombinations<A | B | C>;

type Props = BaseProps & AllPossibleExtensions;

效果说明

  • ResultType/Props自动包含所有需要的组合:基础类型、仅单个扩展类型、任意多个扩展类型的组合。
  • 新增扩展类型时,只需将其加入AllCombinations的泛型参数(如A | B | C | D),无需手动新增交叉类型和联合分支。

内容的提问来源于stack exchange,提问作者Evgeniy Pozdnyakov

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 12:46:57