Manipulation Continues with TypeScript’s Type Operators

Expanding Your TypeScript Toolbox with ‘keyof’ and ‘typeof’

Irene Smolchenko
Bits and Pieces

--

A visually pleasing image of a book titled “The type book”, a branch of delicate blue flowers and a glass of water. All presented in a soothing and romantic pastel color scheme.
Photo by Judith Frietsch on Unsplash

TypeScript offers powerful type operators such as ‘typeof’ and ‘keyof’ that enable developers to effortlessly extract and manipulate types. With these operators, there’s no need to explicitly specify the types, making type extraction and manipulation a smooth process.

With the ‘typeof’ operator, developers can reference the type of variables, functions, or classes as values, enabling dynamic type querying. Similarly, the ‘keyof’ operator empowers developers to extract keys from object types, providing advanced possibilities for type manipulation.

In this article, with the help of clear examples and explanations, we’ll shed light on their potential, equipping you with the knowledge to leverage them effectively in your TypeScript projects.

‘typeof’ Type Operator

In TypeScript, the typeof type operator allows you to capture the type of a value or expression at compile-time. It enables you to refer to the type of a variable, function, or class without actually creating an instance of it.

The typeof operator is used in the following format: typeof x, where x is a value or expression you want to capture the type of.
Let’s see some examples:

  1. The typeof operator can be used to create a custom type based on the type of variables.
‘nickname’ does not exist in type UserType

2. By combining the typeof operator and theReturnType utility type, you can define a custom type that only accepts data types matching the return type of a specific function.
The ReturnType is a utility type that extracts the return type of a function, allowing you to capture and utilize the specific type that a function returns. If you want to learn more about ReturnType, check out the article titled TypeScript’s Type Manipulations which explains it in detail.

‘number’ is not assignable to type ‘string’

Limitations

TypeScript intentionally limits the sorts of expressions you can use typeof on. Specifically, it’s only legal to use typeof on identifiers (i.e. variable names) or their properties. This helps avoid the confusing trap of writing code you think is executing, but isn’t.”

Here is an example:

‘typeof’ operator must be a single identifier (variable), or property
  • PersonObjectType = typeof personObject;
    is valid, of type { name: string; age: number; }
  • PersonAgeType = typeof personAge; — is valid, of type number.
  • PersonNameTypeValid = Person["name"]; — Similarly to personAge, the lookup type Person["name"] allows accessing the property(‘name’) dynamically based on its key.
    The lookup type is closely related to keyof and is used to retrieve the type of a specific property based on its key.

‘keyof’ Type Operator

The keyof index type operator allows you to extract the union of all keys from a given object type. It enables you to work with keys dynamically and perform various operations based on those keys. The keyof operator is commonly used in combination with mapped types.

Keep scrolling for examples below.

  1. Indexed Access and Key Retrieval
    The primary use of keyof is to retrieve all the keys from an object type.
    The keyof operator is often used with indexed access types to access or manipulate specific properties of an object type dynamically.

Let’s break down the code step by step:

  • DataType refers to the type of the objects in the items array.
  • KeyType represents the type of the key that is passed to the function.
  • By using KeyType extends keyof DataType, you're enforcing that the key parameter provided to the function must be a valid key of the DataType object.
    extends is a TypeScript keyword used to constrain the generic type parameter.
    keyof SomeType is a TypeScript operator that represents the union of all possible keys of the SomeType object. It extracts the keys of the SomeType object as a string or a string literal type.
  • DataType[KeyType] is an indexed access type in TypeScript. It retrieves the type of the property in DataType that corresponds to the KeyType.
  • Mind the [], that denotes an array type in TypeScript.

One cool 😎 and convenient feature is that when invoking the function and selecting the key, by typing an empty string (""), you will automatically get the available options derived from the DataType object.

Finally, the available outputs in this example are:

2. Mapped Types and Constraints
The shown below can be helpful when you want to ensure that certain properties in an object type cannot be modified after initialization.

Let’s break down the code step by step:

  • We first define a type Person (an example object type) representing an object with two properties: name of type string and age of type number.
  • The ReadonlyPerson type is defined as a generic type that takes a type parameter T. It represents an object type where all the properties are marked as readonly.
  • { readonly [K in keyof T]: T[K]; } defines an object type with the same keys as T, where each property is of readonly access.
    [K in keyof T] is a mapped type syntax that iterates over each key K in the union of all keys (keyof T) of type T.
  • type ReadonlyPersonType = ReadonlyPerson<Person>;
    Here, we use the ReadonlyPerson type and specify Person as the type argument (T). This creates a new type ReadonlyPersonType where all properties are readonly versions of the corresponding properties in Person.
  • By creating a variable of the typeReadonlyPersonType we ensure its immutability for the properties of a Person object.

‘keyof typeof’

The combination keyof typeof allows you to extract keys from a type. It is typically used to retrieve the keys of an object or the properties of a class as a union type. For example:

interface Fruit {
name: string;
color: string;
taste: string;
}

type FruitKeys = keyof typeof Fruit;
// Equivalent to: type FruitKeys = "name" | "color" | "taste"

function getProperty(fruit: typeof Fruit, key: FruitKeys) {
return fruit[key];
}

const apple: Fruit = {
name: "Apple",
color: "Red",
taste: "Sweet",
};

const color = getProperty(apple, "color"); // Accessing property "color" from the apple object
console.log(color); // Output: "Red"

💡 Consider using an open-source toolchain such as Bit for applying a component-driven approach to building your TypeScript projects. With Bit you can easily share, discover, and reuse individual components across different projects, which can significantly reduce code duplication and improve code quality.

Learn more:

If you’d like to further dive into TypeScript, you might find some of my other articles on type manipulation useful. For example, you can check out TypeScript’s Type Manipulations.

I’d also like to give a shout-out to Jun Tsunokawa for his article on “How to Use keyof typeof in TypeScript”, where he provides a great example in the world of React!

Conclusion

We’ve explored the power of TypeScript’s ‘typeof’ and ‘keyof’ operators, and explained them clearly using examples giving you the tools to use them effectively in your projects. I hope you found this post helpful.

Stay tuned for future content! If you’re new here, feel free to explore the TypeScript library 📚, or my other posts and follow me for updates and more valuable insights.

By buying me a virtual croissant on Buy Me a Coffee, you can directly support my creative journey. Your contribution helps me continue creating high-quality content. Thank you for your support!

Build Apps with reusable components, just like Lego

Bit’s open-source tool help 250,000+ devs to build apps with components.

Turn any UI, feature, or page into a reusable component — and share it across your applications. It’s easier to collaborate and build faster.

Learn more

Split apps into components to make app development easier, and enjoy the best experience for the workflows you want:

Micro-Frontends

Design System

Code-Sharing and reuse

Monorepo

--

--

🍴🛌🏻 👩🏻‍💻 🔁 Front End Web Developer | Troubleshooter | In-depth Tech Writer | 🦉📚 Duolingo Streak Master | ⚛️ React | 🗣️🤝 Interviews Prep