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

如何基于元组首元素推导第二个元素的类型(含对象点标记)

实现严格类型安全的两层对象路径元组

需求是创建最多两层的类型安全对象路径数组,确保只有合法的路径组合被允许——比如拦截["weekend", "monday"]这种无效组合,同时支持单段路径(如["year"]),且路径长度超过2时直接报错。

先看原代码的问题:

interface Days {
    monday: string;
    tueday: string;
    wednesday: string;
    thursday: string;
    friday: string;
    saturday: string;
    sunday: string;
}

interface Weekend {
    saturday: string;
    sunday: string;
}

interface Example {
    days: Days;
    weekend: Weekend;
    year: string;
}

type KeysOfUnions<T> = T extends T ? keyof T : never;
type ExamplePath<T extends keyof Example = keyof Example> = [T, KeysOfUnions<Example[T]>?];

const correctlyErrors: ExamplePath = ["days", "test"]; // 正确报错
const allowsCorrectPath: ExamplePath = ["days", "monday"]; // 正确
const allowsIncorrectPaths: ExamplePath = ["weekend", "monday"]; // 错误:允许了无效组合

原类型通过KeysOfUnions把所有嵌套类型的键合并成了一个大联合,导致不同父键对应的子键被混在一起,无法约束["weekend", "monday"]这种非法组合。同时直接对Example[T](联合类型)用keyof会因为包含基础类型(如string)而报错。

解决方案:基于父键动态推导子键的联合元组类型

我们可以用分布式条件类型和映射类型,让元组的第二个元素类型严格依赖于第一个元素的具体值:

// 通用类型:生成目标对象的所有合法两层/单层路径元组
type TwoLevelPath<T> = 
  // 单段路径:所有顶层键,元组长度固定为1
  | [keyof T]
  // 两段路径:仅当顶层键对应的值是对象时,生成「顶层键 + 子键」的元组
  | { [K in keyof T]: T[K] extends object ? [K, keyof T[K]] : never }[keyof T];

// 针对Example接口生成路径类型
type ExamplePath = TwoLevelPath<Example>;

测试效果

const correctlyErrors: ExamplePath = ["days", "test"]; // ❌ 报错:"test"不属于Days的键
const allowsCorrectPath: ExamplePath = ["days", "monday"]; // ✅ 合法
const blocksInvalidPaths: ExamplePath = ["weekend", "monday"]; // ❌ 报错:"monday"不属于Weekend的键
const allowsSingleSegment: ExamplePath = ["year"]; // ✅ 合法
const rejectsLongerPaths: ExamplePath = ["days", "monday", "extra"]; // ❌ 报错:元组长度超过2

类型工作原理

  1. 单段路径支持:[keyof T]直接生成所有顶层键的单元素元组,确保像["year"]这种无嵌套的路径合法。
  2. 两段路径约束:通过映射类型遍历每个顶层键K,判断T[K]是否是对象类型(排除字符串、数字等基础类型):
    • 如果是对象,生成[K, keyof T[K]]的元组,只允许该顶层键对应的合法子键;
    • 如果不是对象,返回never(会被联合类型自动忽略)。
  3. 自动过滤无效组合:最终的联合类型只包含所有合法的路径元组,不同顶层键对应的子键不会交叉混淆。

适配多层嵌套场景

即使你的实际接口有5层嵌套,这个类型依然适用——它只关注前两层的键,自动忽略更深的层级,完全符合需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 07:31:16