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

如何基于嵌套字典结构的TypeScript接口动态声明同名键的类型?

如何基于嵌套字典结构的TypeScript接口动态声明同名键的类型?

我太懂这种需求了——硬抄内层类型定义不仅麻烦,以后原接口改了还要同步更新,完全是给自己挖坑!你已经走到一半了,再往前推一步就能搞定,我来给你拆解清楚。

首先先明确你的原接口结构:

export interface components {
  schemas: {
    Subscriber: {
      subscriber?: {
        subscriptions?: { [key: string]: { key1?: string; key2?: string; key3?: string; } }
      }
    }
  }
}

你已经能通过components["schemas"]["Subscriber"]["subscriber"]拿到subscriber的类型,但因为subscriber和subscriptions都是可选属性(带?),直接访问深层属性会碰到undefined的干扰,而且我们最终要的是subscriptions里每个键对应的值类型。

这里的核心技巧是用TypeScript索引访问类型结合NonNullable处理可选属性,再用T[keyof T]提取对象的值类型。

分步实现方案

  1. 先去掉可选属性的undefined干扰,拿到确定的subscriptions类型
  2. 提取subscriptions中所有值的类型(也就是你要的Subscription)

具体代码如下:

// 第一步:拿到去掉undefined的subscriber类型,再取出subscriptions的类型
type Subscriptions = NonNullable<components["schemas"]["Subscriber"]["subscriber"]>["subscriptions"];

// 第二步:提取subscriptions的值类型,也就是目标Subscription
type Subscription = NonNullable<Subscriptions>[keyof NonNullable<Subscriptions>];

简化写法(一行搞定)

如果觉得分步写太啰嗦,也可以把逻辑合并成一行,可读性也不差:

type Subscription = NonNullable<
  NonNullable<components["schemas"]["Subscriber"]["subscriber"]>["subscriptions"]
>[keyof NonNullable<
  NonNullable<components["schemas"]["Subscriber"]["subscriber"]>["subscriptions"]
>];

更优雅的复用方式

如果以后经常需要提取对象的值类型,可以定义一个通用工具类型:

// 通用工具类型:提取对象所有值的类型
type ValueOf<T> = T[keyof T];

// 用工具类型简化Subscription的定义
type Subscription = ValueOf<
  NonNullable<
    NonNullable<components["schemas"]["Subscriber"]["subscriber"]>["subscriptions"]
  >
>;

为什么这能生效?

  • NonNullable<T>:把类型T中的undefined和null排除掉,因为你的subscriber和subscriptions都是可选的,直接访问会包含undefined,必须先排除才能安全访问深层属性。
  • T[keyof T]:这是TypeScript提取对象值类型的经典技巧——keyof T会拿到对象T的所有键的联合类型,用这个联合类型去索引T,就会得到所有值的联合类型。在你的场景里,所有值的类型都是一样的,所以最终结果就是你要的单一类型。

这样一来,不管以后components接口里的最内层类型怎么改,Subscription都会自动同步更新,完全不用手动复制粘贴,完美实现动态推导的需求!

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.08 12:04:33