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

如何不使用as const从深度嵌套对象推断字面量类型?

如何让TypeScript工具类型LeafValues自动保留字面量类型(无需as const)?

问题背景

你想要实现一个LeafValues工具类型,从嵌套对象中提取最深层的非对象值,并且保留它们的字面量类型(比如"hello"而非string)。当前的实现如下:

type LeafValues<T extends object> = {
  [K in keyof T]: T[K] extends object ? LeafValues<T[K]> : T[K];
}[keyof T];

但直接使用时,TypeScript会把字面量类型拓宽为原始类型:

const obj = {
  foo: "hello",
  bar: {
    baz: "world",
  },
};

type Result = LeafValues<typeof obj>; // 实际为 string,预期是 "hello" | "world"

虽然用as const可以解决,但你不想给每个对象都加这个断言。

核心限制:TypeScript的类型拓宽机制

问题的根源在于TypeScript的字面量拓宽规则:当你直接声明一个对象变量时,TypeScript会自动把字面量类型(比如"hello")拓宽为对应的原始类型(string),目的是让变量后续可以被重新赋值。只有当你用as const断言,或者通过特定方式(比如const泛型)捕获类型时,才会保留字面量的精确类型。

LeafValues工具类型只能基于传入的类型参数工作,而typeof obj已经是拓宽后的{ foo: string; bar: { baz: string } },所以类型系统无法从这个拓宽后的类型还原出原始的字面量信息。

可行的变通方案

1. 使用const泛型辅助函数(推荐)

TypeScript 5.0及以上支持const泛型,可以让函数自动将传入的对象字面量按as const的方式推断类型,无需手动添加断言:

// 定义一个辅助函数,用const泛型捕获字面量类型
const createStrictObj = <const T extends object>(obj: T) => obj;

// 创建对象时用这个函数包裹
const obj = createStrictObj({
  foo: "hello",
  bar: {
    baz: "world",
  },
});

type Result = LeafValues<typeof obj>; // "hello" | "world" ✅

如果需要对象属性是可写的(const泛型会让属性变成只读),可以再加一层类型转换去掉readonly:

type Writable<T> = { -readonly [K in keyof T]: T[K] };

const createStrictObj = <const T extends object>(obj: T): Writable<T> => 
  obj as Writable<T>;

const obj = createStrictObj({
  foo: "hello",
  bar: {
    baz: "world",
  },
});

obj.foo = "hi"; // 允许赋值,类型依然保留字面量约束
type Result = LeafValues<typeof obj>; // "hello" | "world" ✅

2. 手动指定对象的精确类型

如果不想用辅助函数,可以直接给对象指定包含字面量的类型定义,虽然繁琐但有效:

// 手动定义包含字面量的类型
type ExactObjType = {
  foo: "hello";
  bar: {
    baz: "world";
  };
};

// 让对象符合这个类型
const obj: ExactObjType = {
  foo: "hello",
  bar: {
    baz: "world",
  },
};

type Result = LeafValues<ExactObjType>; // "hello" | "world" ✅

结论

目前无法仅通过修改LeafValues类型本身实现需求,因为类型系统无法从拓宽后的原始类型逆向还原字面量信息。最便捷的方案是使用const泛型辅助函数,在对象创建阶段就保留字面量类型,同时避免手动添加as const。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 11:35:02