You need to enable JavaScript to run this app. Typescript中从类型参数获取类型补集解决泛型赋值报错问题
优惠活动
大模型
产品
解决方案
定价
更多

Typescript中从类型参数获取类型补集解决泛型赋值报错问题

问题背景

这是项目实际问题的简化通用版本,项目需要给完全没有做类型设计、存在大量变更操作的老旧JS代码补充TS类型定义,且无权修改原有结构。
基础结构上可以挂载各类「扩展」,需要将扩展传入函数后在原基础上追加其他扩展,同时要保持所有逻辑为泛型。

初始问题

方案初步实现后Typescript抛出如下错误:

Type 'WrapperType' is not assignable to type 'Wrapper<ExtensionOf<WrapperType>>'.
  Type 'Wrapper<{}>' is not assignable to type 'Wrapper<ExtensionOf<WrapperType>>'.
    Type '{}' is not assignable to type 'ExtensionOf<WrapperType>'.

相关代码如下:

function fn<WrapperType extends Wrapper>(wrapper: WrapperType):
    Wrapper<
        ExtensionOf<WrapperType> // 此处类型推导异常,目标是在函数内追加更多扩展
    > {
    return wrapper; // 此处抛出类型错误
}

type BaseObj = {
    prop: number;
};

type Wrapper<
    Extension = {} // 曾尝试将默认值替换为any
> = {
    obj: Extension & BaseObj; // 曾尝试给Extension包裹Partial
}

// 由于Extension存在默认值,可以交换BaseObj和WrapperType['obj']的位置
type ExtensionOf<WrapperType extends Wrapper> = Complement<BaseObj, WrapperType['obj']>;

type Complement<ExcludePropertiesFromThisType, Type extends ExcludePropertiesFromThisType> = Omit<Type, keyof ExcludePropertiesFromThisType>;

修改后出现的新问题

将函数修改为如下写法后出现更明确的类型错误:

function fn<WrapperType extends Wrapper>(wrapper: Wrapper):
    Wrapper<ExtensionOf<WrapperType>> {
    return {
        ...wrapper,
    };
}

对应报错:

Type '{ obj: BaseObj; }' is not assignable to type 'Wrapper<ExtensionOf<WrapperType>>'.
  Types of property 'obj' are incompatible.
    Type 'BaseObj' is not assignable to type 'ExtensionOf<WrapperType> & BaseObj'.
      Type 'BaseObj' is not assignable to type 'ExtensionOf<WrapperType>'.

更具体的报错为:Type 'BaseObj' is not assignable to type 'ExtensionOf<WrapperType> & BaseObj'.

预期实现效果

最终要达成的效果如下:

type WithOtherExtension = {
    yetAnotherProp: boolean
}

const myWrapper: Wrapper<{ otherProp: number }> = {
    obj: {
        prop: 1,
        otherProp: 2,
    },
};

const myModifiedWrapper: Wrapper<{ otherProp: number } & WithOtherExtension> = fn(myWrapper);

console.log(myModifiedWrapper.obj.prop, myModifiedWrapper.obj.yetAnotherProp);

function fn<WrapperType extends Wrapper>(wrapper: WrapperType):
    Wrapper<
        ExtensionOf<WrapperType> & WithOtherExtension 
    > {
    // 不希望使用@ts-ignore忽略类型错误
    const newWrapper: Wrapper<ExtensionOf<WrapperType> & WithOtherExtension> = wrapper;
    newWrapper.obj.yetAnotherProp = true; // 核心目标是支持该操作

    return newWrapper;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.16 09:06:06