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

TypeScript中如何使key in定义的嵌套属性无需全部声明?

问题分析与解决方案

问题场景

现有TypeScript代码结构如下,在将导出对象断言为Strategies类型时遇到TS2352错误,原因是原类型强制每个网络下必须声明所有SupportedAsset对应的策略,但实际需求是允许只声明部分资产策略,同时保留类型检查。

declare type NetworkName =
  | 'netA'
  | 'netB'
  | 'netC'

enum SupportedAsset {
  ASSETA = 'assetA',
  ASSETB = 'assetB',
  ASSETC = 'assetC',
}

interface OrderStrategy {
  propA: number
  propB: number
  propC: string
}

const defaultSettings: OrderStrategy = {
  propA: 1,
  propB: 0.1,
  propC: 'foo'
}

// 原类型定义,强制每个网络包含所有资产策略
type Strategies = {
  [key in NetworkName]: {
    [key in SupportedAsset]: OrderStrategy
  }
}

// 导出对象仅声明了部分资产策略,导致类型断言报错
export default {
  netA: {
    assetA: {
      ...defaultSettings,
    },
  },
  netB: {
    assetA: {
      ...defaultSettings,
    },
  },
  netC: {
    assetA: {
      ...defaultSettings,
    },
  }
} as Strategies

错误信息:

TS2352: Conversion of type to type Strategies may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to unknown first.

解决方案

修改Strategies类型定义,将每个网络下的资产策略集合改为可选属性,这样既不需要声明所有资产,又能保留对已声明策略的类型检查。有两种等价实现方式:

方式一:使用Partial工具类型

Partial<T>会将类型T的所有属性转为可选:

type Strategies = {
  [key in NetworkName]: Partial<{
    [key in SupportedAsset]: OrderStrategy
  }>
}

方式二:在映射类型中直接添加?

在资产的映射类型后添加?标记,显式将每个资产属性设为可选:

type Strategies = {
  [key in NetworkName]: {
    [key in SupportedAsset]?: OrderStrategy
  }
}

效果验证

修改后,导出对象仅声明部分资产策略时不会再报错,同时TypeScript会严格检查:

  • 网络名称必须是NetworkName中的有效值
  • 资产名称必须是SupportedAsset对应的字符串值
  • 每个资产的策略必须符合OrderStrategy接口定义

这样既满足了“不需要支持所有策略”的需求,又不会丢失类型检查的严格性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 09:32:36