valueof in TypeScript: how to get the value type from an object

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Is there a `valueof` similar to `keyof` in TypeScript? Optimization and performance

\n\n

Have you ever written TypeScript and caught yourself thinking: "I have keyof for keys, but where is valueof for values?" If so — you are not alone. This question on Stack Overflow has gathered thousands of views, and today we will break it down from start to finish. But not just as abstract theory, but with a focus on optimization and performance of your code. Let's go!

\n\n

Why does `keyof` exist, but `valueof` does not?

\n\n

TypeScript has a built-in utility type keyof. It takes an object type and returns a union of all its keys:

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

What about values? You want to get string | number | boolean from the same type. There is no such thing in the TypeScript standard library. Why? Because valueof is not just a "reverse operation". An object can have many keys with the same types, and we need to decide how to combine them. But that doesn't mean we can't write our own valueof!

\n\n

Creating your own `ValueOf`

\n\n

The simplest way is to use an indexed access type in combination with keyof:

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

That's it! We just created a generic type ValueOf that works like valueof. But let's dig deeper — how does this affect performance and how to use it wisely.

\n\n

Optimization: when `ValueOf` saves you from duplication

\n\n

Imagine you have a configuration object with dozens of fields. You want to write a function that accepts any value from this object. Without ValueOf, you would list the types manually:

\n\n
type Config = {\n  apiUrl: string;\n  timeout: number;\n  retries: number;\n  debug: boolean;\n};\n\n// Bad: type duplication\nfunction setConfigValue(key: string, value: string | number | boolean) {\n  // ...\n}
\n\n

And now with ValueOf:

\n\n
// Good: automatically picks up all value types\nfunction setConfigValue(key: keyof Config, value: ValueOf<Config>) {\n  // TypeScript knows that value can only be string | number | boolean\n}
\n\n

This not only reduces code but also makes it self-documenting. If you add a new field to Config, TypeScript will automatically pick up the new type. Fewer errors — more development performance.

\n\n

Advanced `ValueOf` with conditional types

\n\n

Sometimes you need to get values only from certain keys. For example, all numeric values. This is where conditional types come to the rescue:

\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

This technique is especially useful when working with large types: you can filter only the needed values and avoid unnecessary runtime checks. Optimization at the type level is free performance, because types disappear during compilation.

\n\n

Runtime performance: is it necessary?

\n\n

An important point: ValueOf is a purely type-level construct. It does not generate any JavaScript code. But its correct use can indirectly improve the performance of your application:

\n\n
    \n
  • Fewer bugs — less time spent debugging.
  • \n
  • Stricter typing — the compiler catches

Blogs

Book Recommendations