TypeScript 中的 valueof:如何从对象中获取值的类型

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

TypeScript 中是否存在类似 `keyof` 的 `valueof`?优化与性能

\n\n

你是否曾在编写 TypeScript 时有过这样的想法:“我有用于键的 keyof,那用于值的 valueof 在哪里?” 如果是这样——你并不孤单。这个问题在 Stack Overflow 上获得了数千次浏览,今天我们将从头到尾深入探讨它。但这不仅仅是抽象的理论,而是聚焦于你代码的 优化 和 性能。开始吧!

\n\n

为什么有 `keyof`,却没有 `valueof`?

\n\n

TypeScript 有一个内置的工具类型 keyof。它接受一个对象类型并返回其所有键的联合类型:

\n\n
type Person = {\n  name: string;\n  age: number;\n  isActive: boolean;\n};\n\ntype PersonKeys = keyof Person; // "name" | "age" | "isActive"
\n\n

那值呢?我们希望从同一个类型中得到 string | number | boolean。TypeScript 的标准库中没有这个功能。为什么?因为 valueof 不仅仅是“反向操作”。一个对象可能有许多具有相同类型的键,我们需要决定如何合并它们。但这并不意味着我们不能编写自己的 valueof!

\n\n

创建我们自己的 `ValueOf`

\n\n

最简单的方法是使用 索引访问类型(indexed access type)结合 keyof:

\n\n
type ValueOf<T> = T[keyof T];\n\ntype PersonValues = ValueOf<Person>; // string | number | boolean
\n\n

就是这样!我们刚刚创建了一个泛型类型 ValueOf,它像 valueof 一样工作。但让我们深入探讨一下——这对性能有何影响,以及如何巧妙地使用它。

\n\n

优化:当 `ValueOf` 避免重复时

\n\n

想象一下,你有一个包含几十个字段的配置对象。你想编写一个接受该对象中任意值的函数。如果没有 ValueOf,你需要手动枚举类型:

\n\n
type Config = {\n  apiUrl: string;\n  timeout: number;\n  retries: number;\n  debug: boolean;\n};\n\n// 不好:类型重复\nfunction setConfigValue(key: string, value: string | number | boolean) {\n  // ...\n}
\n\n

现在使用 ValueOf:

\n\n
// 好:自动捕获所有值的类型\nfunction setConfigValue(key: keyof Config, value: ValueOf<Config>) {\n  // TypeScript 知道 value 只能是 string | number | boolean\n}
\n\n

这不仅减少了代码量,还使其 自文档化。如果你在 Config 中添加一个新字段,TypeScript 会自动捕获新类型。更少的错误意味着更高的开发效率。

\n\n

高级 `ValueOf` 与条件类型

\n\n

有时你需要仅获取特定键的值。例如,所有数值类型的值。这时 条件类型(conditional types)就派上用场了:

\n\n
type NumericValues<T> = {\n  [K in keyof T]: T[K] extends number ? T[K] : never;\n}[keyof T];\n\ntype ConfigNumeric = NumericValues<Config>; // number (timeout | retries)
\n\n

这种技巧在处理大型类型时特别有用:你可以过滤出所需的值,并避免运行时的多余检查。类型层面的优化是 免费的性能提升,因为类型在编译时会被移除。

\n\n

运行时性能:有必要吗?

\n\n

重要的一点:ValueOf 纯粹是一个类型层面的构造。它不会生成任何 JavaScript 代码。但正确使用它可以 间接提升 你应用程序的性能:

\n\n
    \n
  • 更少的 Bug —— 更少的调试时间。
  • \n
  • 更严格的类型检查 —— 编译器能捕获
  • \n

博客

书籍推荐