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

如何在将对象转为接口类型后获取原始嵌套对象类型?

解决TypeScript中指定接口后丢失原始嵌套键类型的问题

问题分析

当把具有具体嵌套结构的对象赋值给带字符串索引签名的Routing接口后,TypeScript会擦除对象的具体类型信息,仅保留接口定义的宽泛类型。这导致NestedKeyOf工具类型无法解析出原始的具体嵌套键联合类型,只能返回string。

解决方案

方法1:通过泛型函数约束类型并保留原始结构

不直接给变量指定Routing类型,而是用泛型函数验证对象是否符合Routing结构,同时保留原始对象的具体类型:

interface Routing {
  [SEGMENT: string]: Routing | number | string;
}

// 泛型函数,约束对象符合Routing结构,同时保留原始类型
function createRouting<T extends Routing>(route: T): T {
  return route;
}

const exampleRoutes2 = createRouting({
  api: {
    products: "myProductEndpoint",
    customers: "myCustomerEndpoint",
  },
});

// type test2 = "api" | "api.products" | "api.customers"
type test2 = NestedKeyOf<typeof exampleRoutes2>;

泛型T会捕获原始对象的具体类型,T extends Routing确保对象符合接口要求,既完成类型校验,又保留了原始嵌套键信息。

方法2:使用as const结合泛型约束(适用于字面量对象)

如果对象是字面量形式,用as const强制保留字面量类型,再通过泛型验证其符合Routing结构:

interface Routing {
  [SEGMENT: string]: Routing | number | string;
}

const exampleRoutes = {
  api: {
    products: "myProductEndpoint",
    customers: "myCustomerEndpoint",
  },
} as const;

// 泛型类型,验证T是否符合Routing结构
type EnsureRouting<T> = T extends Routing ? T : never;

const exampleRoutes2: EnsureRouting<typeof exampleRoutes> = exampleRoutes;

// type test2 = "api" | "api.products" | "api.customers"
type test2 = NestedKeyOf<typeof exampleRoutes2>;

as const让TypeScript将对象的属性值和键都视为字面量类型,EnsureRouting泛型则用于验证该类型是否符合Routing结构,避免直接赋值导致的类型擦除。

方法3:将Routing改为泛型接口

把原本的索引签名接口改成泛型版本,让它可以接受具体的键类型,从而保留嵌套结构的类型信息:

// 泛型版本的Routing接口
type Routing<T extends Record<string, any>> = {
  [K in keyof T]: T[K] extends object ? Routing<T[K]> : T[K];
};

const exampleRoutes = {
  api: {
    products: "myProductEndpoint",
    customers: "myCustomerEndpoint",
  },
};

// 推导具体的Routing类型
type ExampleRouting = Routing<typeof exampleRoutes>;

const exampleRoutes2: ExampleRouting = exampleRoutes;

// type test2 = "api" | "api.products" | "api.customers"
type test2 = NestedKeyOf<typeof exampleRoutes2>;

泛型T捕获具体的对象结构,Routing类型会递归适配嵌套对象的结构,既保留原始类型信息,又完成结构约束。

核心原理

问题的根源在于字符串索引签名会擦除具体的键类型信息,导致TypeScript无法识别对象的具体嵌套键。上述方案的核心都是通过泛型或as const保留原始对象的具体类型,同时确保对象符合Routing的结构要求,避免类型擦除。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 00:49:56