如何从TypeScript嵌套类型中提取指定子类型?
解决TypeScript深层嵌套可选类型的属性提取问题
针对你遇到的无法直接获取ActiveOrderQuery["activeOrder"]["lines"]类型的问题,核心原因是activeOrder属于可选且可能为null/undefined的类型,TypeScript不允许直接访问这类类型的嵌套属性。以下是两种无需手动编写类型的解决方案:
方案1:直接使用NonNullable逐层排除空值
如果只是固定两层嵌套的场景,可以通过两次NonNullable工具类型排除activeOrder的空值可能性,再访问目标属性:
type OrderLines = NonNullable<NonNullable<ActiveOrderQuery["activeOrder"]>["lines"]>;
- 第一层
NonNullable<ActiveOrderQuery["activeOrder"]>剔除activeOrder的null | undefined类型,得到确定的Order对象类型 - 第二层直接访问
["lines"]即可获取数组类型,你的定义中lines本身非可选,这一步的NonNullable可省略,但保留会让类型更严谨
方案2:通用深层属性提取工具类型
如果未来需要提取更深层次的嵌套属性,或者想统一复用逻辑,可以封装一个通用工具类型,支持用.分隔的路径字符串自动解析嵌套类型:
type DeepPick<T, Path extends string> = Path extends `${infer FirstKey}.${infer RestPath}` ? FirstKey extends keyof T ? DeepPick<NonNullable<T[FirstKey]>, RestPath> : never : Path extends keyof T ? NonNullable<T[Path]> : never; // 使用示例 type OrderLines = DeepPick<ActiveOrderQuery, "activeOrder.lines">;
这个工具类型会递归解析路径字符串,逐层排除每个节点的null | undefined类型,最终返回目标属性的确定类型。无论未来代码生成的类型嵌套层级如何变化,只要路径字符串正确,就能自动同步获取对应的类型。
最终效果验证
对于你提供的ActiveOrderQuery类型,上述两种方案最终都会生成与代码生成结果完全一致的类型:
Array<{ __typename?: 'OrderLine'; id: string; quantity: number; linePrice: number; linePriceWithTax: number; unitPrice: number; unitPriceWithTax: number; productVariant: { __typename?: 'ProductVariant'; name: string; featuredAsset?: { __typename?: 'Asset'; preview: string; } | null; }; discounts: Array<{ __typename?: 'Discount'; type: AdjustmentType; description: string; amount: number; amountWithTax: number; }>; }>
内容的提问来源于stack exchange,提问作者nxyt
相关产品推荐
相关产品推荐

