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

使用Extract工具类型收窄联合类型时出现类型错误

TypeScript类型兼容问题:修复getCoinWithBalance与getAsset的类型不匹配

问题背景

尝试通过Extract工具类型,基于EthereumViewModel的泛型参数C(约束为'eth' | 'polygon'),从FlatAssetWithBalance联合类型中筛选对应链的资产类型,作为getCoinWithBalance的返回类型,但该类型与getAsset函数的返回类型不匹配,导致return行报错。

错误信息

类型 'BaseAsset & { chainId: C; contract: string; }' 不能赋值给类型 'EthChainFlatAssetWithBalance<C>'。
  类型 'BaseAsset & { chainId: C; contract: string; }' 不能赋值给类型 'Extract<BaseAsset & { contract: string; chainId: "polygon"; }, { chainId: C; }>'。

类型不匹配的原因

  1. EthChainFlatAssetWithBalance<C>的本质:它是通过Extract从FlatAssetWithBalance这个固定的联合类型中,筛选出chainId等于C的子类型。FlatAssetWithBalance是三个预先定义好的具体联合项,因此EthChainFlatAssetWithBalance<C>的结果是联合类型中的某一个具体成员(比如当C='polygon'时,就是BaseAsset & { contract: string; chainId: "polygon"; })。
  2. getAsset返回类型的本质:它是一个动态构造的泛型交叉类型——BaseAsset & { chainId: C; contract: string; },这个类型是基于泛型参数C实时组合出来的。

TypeScript的类型系统无法自动证明:对于任意符合约束的C,Extract出来的具体子类型和动态构造的交叉类型是完全等价的。尤其是当C是未具体化的泛型参数时,TypeScript会认为这两个类型属于不同的“类型构造方式”,因此拒绝赋值。


修复方案

方案1:调整EthChainFlatAssetWithBalance的定义(推荐)

直接让EthChainFlatAssetWithBalance<C>的类型和getAsset的返回类型对齐,放弃使用Extract,改用交叉类型构造:

// 替换原来的EthChainFlatAssetWithBalance定义
type EthChainFlatAssetWithBalance<C extends EthereumChainId> = BaseAsset & {
  chainId: C;
  contract: string;
};

这样getCoinWithBalance的返回类型和getAsset的返回类型完全一致,类型错误会直接消失,同时代码更简洁、类型关系更明确。

方案2:使用类型断言(临时兼容)

如果无法修改EthChainFlatAssetWithBalance的定义,可以在返回时添加类型断言,明确告诉TypeScript这两个类型是等价的:

class EthereumViewModel<C extends EthereumChainId> {
    chainId: C = 'eth' as C;

    getCoinWithBalance(): EthChainFlatAssetWithBalance<C> {
        return getAsset(this.chainId) as EthChainFlatAssetWithBalance<C>;
    }
}

这种方式适合无法修改原有类型定义的场景,但不如方案1优雅,因为它依赖开发者的类型判断,而非TypeScript的自动推导。

额外优化:简化FlatAssetWithBalance的定义

可以基于已有的BlockchainInfo类型重构FlatAssetWithBalance,避免重复代码:

type FlatAssetWithBalance = BaseAsset & BlockchainInfo & { amount: number };

这样FlatAssetWithBalance会自动继承BlockchainInfo的所有链类型定义,后续扩展链类型时无需重复修改。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 21:37:42