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

TypeScript基于枚举的嵌套条件类型对象实例化报错求助

TypeScript联合类型返回值类型不兼容问题解决

问题背景

项目中需要使用以下联合类型:

type MyObjectType = {
    vtype: "text";
    vvalues: string[];
} | {
    vtype: "num1";
    vvalues: number[];
} | {
    vtype: "num2";
    vvalues: number[];
}

通过枚举重构后得到如下代码:

enum MyValues {
    TEXT = 'text',
    NUM1 = 'num1',
    NUM2 = 'num2'
}
type MyValueTypes = `${MyValues}`

type MyValue<T extends MyValueTypes> =
    T extends 'num1' | 'num2' ? number :
    T extends 'text' ? string :
    never;

type ObjImpl<T> =
    T extends MyValueTypes ? {
        vtype: T;
        vvalues: MyValue<T>[];
    } : never;

type MyObjectType = ObjImpl<MyValueTypes>;

编写实例化函数时,函数调用的类型校验正常,但返回值出现类型不兼容错误:

function fillProps<T extends MyValueTypes>(vtype: T, item: MyValue<T>): MyObjectType {
    return {
        vtype,
        // ERROR: Type '(string | number)[]' is not assignable to type 'string[] | number[]'.
        vvalues: [item]
    }
}

fillProps(MyValues.TEXT, 78) // ERROR: 符合预期
fillProps(MyValues.NUM1, 78) // 符合预期
fillProps(MyValues.TEXT, 'asd') // 符合预期
fillProps(MyValues.NUM2, 'asd') // ERROR: 符合预期

解决方法

方法1:调整函数返回类型为具体泛型类型

将函数返回类型从MyObjectType改为ObjImpl<T>,让TypeScript精确推断返回值的具体类型,而非笼统的联合类型:

function fillProps<T extends MyValueTypes>(vtype: T, item: MyValue<T>): ObjImpl<T> {
    return {
        vtype,
        vvalues: [item]
    }
}

此时返回值会自动匹配T对应的具体子类型,完全符合类型定义,不再出现错误。

方法2:使用类型断言

如果需要保持返回类型为MyObjectType,可以通过类型断言明确告知TypeScript返回值符合目标类型:

function fillProps<T extends MyValueTypes>(vtype: T, item: MyValue<T>): MyObjectType {
    return {
        vtype,
        vvalues: [item]
    } as ObjImpl<T>;
}

ObjImpl<T>是MyObjectType的子类型,该断言安全且能解决类型推断模糊的问题。

问题原因

函数内部TypeScript无法将泛型T对应的MyValue<T>[]精确推断为string[]或number[],只会推断为(string | number)[]。而(string | number)[](元素可混存字符串/数字的数组)与string[] | number[](全字符串或全数字数组的联合)是不同类型,前者无法直接赋值给后者,因此触发类型错误。通过让返回类型更具体或使用断言,即可消除这种类型推断的模糊性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 13:44:56