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

如何从可能为undefined的嵌套TypeScript类型中提取内部属性类型

问题描述

我有一段由graphql codegen自动生成的TypeScript类型(无法手动修改,会随GraphQL查询更新):

type User = { user?: { subscription?: {...} | null | undefined, ... } | null | undefined };

我想提取subscription的类型,于是写了这段代码:

type SubscriptionType = User['user']['subscription'];

但TypeScript抛出了错误:

typescript: Property 'subscription' does not exist on type '{ __typename?: "users" | undefined; subscription?: { __typename?: "subscriptions" | undefined; id: number; activeSince?: any; renewalDate?: any; endingDate?: any; ... 7 more ...; } | null | undefined; } | null | undefined'.

同时SubscriptionType被推断成了any类型。

解决方案

问题出在User['user']的类型是对象 | null | undefined,直接访问subscription时TypeScript无法确定它是否存在于所有可能的分支上。以下是几种安全提取类型的方法:

方法1:逐层条件类型提取

通过条件类型逐层拆解结构,自动处理空值分支:

type GetSubscription<T> = T extends { user?: infer U } 
  ? U extends { subscription?: infer S } 
    ? S 
    : never 
  : never;

type SubscriptionType = GetSubscription<User>;

这个类型会先从User里提取user的类型,再从user的类型里提取subscription的类型,不管中间层有没有null或undefined都能正确处理。

方法2:筛选非空类型后访问

先用Extract把user的非空对象类型筛选出来,再访问subscription:

type NonNullableUser = Extract<User['user'], object>;
type SubscriptionType = NonNullableUser['subscription'];

Extract<User['user'], object>会排除null和undefined,只保留user的对象类型,之后就能安全访问subscription了。

方法3:链式使用NonNullable

如果使用TypeScript 4.5及以上版本,可以用NonNullable链式处理空值:

// 得到subscription的非空类型
type SubscriptionType = NonNullable<NonNullable<User['user']>['subscription']>;

// 如果要保留subscription本身的null/undefined可能性
type SubscriptionType = NonNullable<User['user']>['subscription'];

内层NonNullable处理user的空值,外层处理subscription的空值,按需选择是否保留subscription的空值类型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 06:45:58