Typescript object key types

keyof and Lookup Types in TypeScript

JavaScript is a highly dynamic language. It can be tricky sometimes to capture the semantics of certain operations in a static type system. Take a simple prop function, for instance:

function prop(obj, key)  return objTypescript object key types; >

It accepts an object and a key and returns the value of the corresponding property. Different properties on an object can have totally different types, and we don’t even know what obj looks like.

So how could we type this function in TypeScript? Here’s a first attempt:

function prop(obj: <>, key: string)  return objTypescript object key types; >

With these two type annotations in place, obj must be an object and key must be a string. We’ve now restricted the set of possible values for both parameters. The return type is still inferred to be any , however:

const todo =  id: 1, text: "Buy milk", due: new Date(2016, 11, 31), >; const id = prop(todo, "id"); // any const text = prop(todo, "text"); // any const due = prop(todo, "due"); // any

Without further information, TypeScript can’t know which value will be passed for the key parameter, so it can’t infer a more specific return type for the prop function. We need to provide a little more type information to make that possible.

#The keyof Operator

Enter TypeScript 2.1 and the new keyof operator. It queries the set of keys for a given type, which is why it’s also called an index type query. Let’s assume we have defined the following Todo interface:

interface Todo  id: number; text: string; due: Date; >

We can apply the keyof operator to the Todo type to get back a type representing all its property keys, which is a union of string literal types:

type TodoKeys = keyof Todo; // "id" | "text" | "due"

We could’ve also written out the union type «id» | «text» | «due» manually instead of using keyof , but that would’ve been cumbersome, error-prone, and a nightmare to maintain. Also, it would’ve been a solution specific to the Todo type rather than a generic one.

#Indexed Access Types

Equipped with keyof , we can now improve the type annotations of our prop function. We no longer want to accept arbitrary strings for the key parameter. Instead, we’ll require that the key actually exists on the type of the object that is passed in:

function propT, K extends keyof T>(obj: T, key: K)  return objTypescript object key types; >

TypeScript now infers the prop function to have a return type of T[K] , a so-called indexed access type or lookup type. It represents the type of the property K of the type T . If we now access the three todo properties via the prop method, each one will have the correct type:

const todo =  id: 1, text: "Buy milk", due: new Date(2016, 11, 31), >; const id = prop(todo, "id"); // number const text = prop(todo, "text"); // string const due = prop(todo, "due"); // Date

Now, what happens if we pass a key that doesn’t exist on the todo object?

Invalid key

The compiler complains, and that’s a good thing! It prevented us from trying to read a property that’s not there.

For another real-world example, check out how the Object.entries() method is typed in the lib.es2017.object.d.ts type declaration file that ships with the TypeScript compiler:

interface ObjectConstructor  // .  entriesT extends < Typescript object key types: any >, K extends keyof T>( o: T, ): [keyof T, T[K]][]; // . >

The entries method returns an array of tuples, each containing a property key and the corresponding value. There are plenty of square brackets involved in the return type, admittedly, but there’s the type safety we’ve been looking for!

This article and 44 others are part of the TypeScript Evolution series. Have a look!

Advanced TypeScript Fundamentals

Advanced TypeScript Fundamentals

A deep dive into the fundamnetals of TypeScript’s type system. Learn about the optional chaining ( ?. ) and nullish coalescing ( ?? ) operators, assertion functions, truly private class fields, conditional types, template literal types, adn more.

Источник

Typescript object key types

Notice that we didn’t use typeof, because Person is a type and not an object.

# Create a Type from an object’s Values in TypeScript

To create a type from an object’s values:

  1. Use a const assertion when declaring the object.
  2. Use keyof typeof to get a type that represents the object’s keys.
  3. Index the object’s type at the specific keys to get a type of its values.
Copied!
const employee = id: 1, name: 'Bobby Hadz', salary: 100, > as const; // 👈️ use const assertion // 👇️ type Keys = "id" | "name" | "salary" type Keys = keyof typeof employee; // 👇️ type Values = 1 | "Bobby Hadz" | 100 type Values = (typeof employee)[Keys];

The as const syntax is called a const assertion. We used it to declare an immutable object.

We had to do this because it helps us narrow down the type of the object’s values.

Copied!
// 👇️ const employee: // readonly id: 1; // readonly name: "Bobby Hadz"; // readonly salary: 100; // > const employee = id: 1, name: 'Bobby Hadz', salary: 100, > as const; // 👈️ use const assertion

The values of the object in the example are typed as 1 , Bobby Hadz and 100 , which is exactly what we need to get a type representing the object’s values.

TypeScript is able to be as specific because it knows that the properties are readonly and the values will never change.

# Getting a more generic type of the object’s values

Had we not used a const assertion, we would get much more generic types for the object’s values.

Copied!
const employee = id: 1, name: 'Bobby Hadz', salary: 100, >; // 👇️ type Keys = "id" | "name" | "salary" type Keys = keyof typeof employee; // 👇️ type Values = string | number type Values = (typeof employee)[Keys];

The example doesn’t use a const assertion, so the type of the object’s values are string | number which is probably not what you need.

We used keyof typeof to get the type of the object’s keys.

Copied!
const employee = id: 1, name: 'Bobby Hadz', salary: 100, > as const; // 👇️ type Keys = "id" | "name" | "salary" type Keys = keyof typeof employee; // 👇️ type Values = 1 | "Bobby Hadz" | 100 type Values = (typeof employee)[Keys];

The keyof typeof syntax returns a type that represents all of the object’s keys as strings.

To get a type of the object’s values, we used square brackets and indexed the object using the type of the keys.

You can use this approach to get the type of a value that corresponds to a specific property as well.

Copied!
const employee = id: 1, name: 'Bobby Hadz', salary: 100, > as const; // 👇️ type Keys = "id" | "name" | "salary" type Keys = keyof typeof employee; // 👇️ type Values = 1 | "Bobby Hadz" | 100 type Values = (typeof employee)[Keys]; // 👇️ type V1 = 1 type V1 = (typeof employee)['id']; // 👇️ type V2 = "Bobby Hadz" type V2 = (typeof employee)['name']; // 👇️ type V3 = 100 type V3 = (typeof employee)['salary'];

I wrote a book in which I share everything I know about how to become a better, more efficient programmer.

Источник

TypeScript Keyof

In this article, we will get an insight into the keyof operator used in TypeScript. Like object.keys in JavaScript, the keyof operator has the equivalent concept in TypeScript. Although they have similar functioning, keyof only works on the type level and returns a literal union type but object.keys returns values. The keyof operator takes an object type and returns a string or numeric literal union of its keys.

Introduction

The keyof operator was introduced in TypeScript 2.1s . This keyword has become a building block for advanced typing in TypeScript and it is used very often in the code. It is referred to as the index query operator because the keyword queries the type specified after keyof . The indexed base type query fetches the values from properties and their attributes that are related to elements like default keywords and their data types.

Defining the KeyOf Operator

In TypeScript, the keyof operator is used to fetch the user values. It is majorly used in Generics and follows the format of a union operator and its properties. It retrieves the index for the values that are specified by the users. This operator can be used in objects like collections, and classes that are used to store and retrieve data using key and value pairs. Using the map instance object.keys() method, we can fetch the keys that are stored in the memory.

Syntax

In the above snippet, we have created a class with a name and used a var or let data type with the variable name and called the DemoClass with the keyof operator. When the value is assigned to the variable name, it will display on the output screen.

Using KeyOf with TypeScript generics

The TypeScript keyof operator is used to apply constraints in a generic function.

The above-given function retrieves the type of object property defined using generics. keyof T returns a union of string literal types. Literals are defined as the constant values that are assigned to the constant variables.

K is a string literal type so we use extends keyword to apply constraints on K . The indexed operator objTypescript object key types returns the same type that the property will have.

Now we will see how the getProperty type used below:

The compiler will validate the key to match one of the property names of type T as we have applied the type constraints for the second parameter. The compilation error will occur if we try to pass an invalid key sal .

We can define a union type manually when we don’t use the keyof operator:

Although the same kind of constraint is applied, the manual approach is less maintainable. The definition of type will be duplicated and the change of the original type will not be automatically generated.

Using KeyOf with TypeScript mapped Types

We can use the TypeScript keyof operator with mapped types that converts the existing types with new types by iterating through keys. Mapped types are built on index signatures that are used to define the types of properties that have not been declared already.

Here is an example to transform the FeatureFlags type using the OptionsFlags mapped type.

In the above snippet, OptionsFlags is defined as a generic type that involves a type parameter T. Property in keyof T defines the iteration of the property names of type T, and the square bracket indicates the index signature syntax. Therefore, the OptionsFlags will remap the values to boolean type and contains all the properties of type T.

KeyOf with Explicit keys

The TypeScript keyof operator creates a union type when we use the keyword on an object type with explicit keys.

KeyOf with Index Signatures

The TypeScript keyof operator can be used with index signatures to remove the index type. Index signatures are used to represent the type of object where the values of the object are of consistent types.

Using KeyOf Conditional Mapped Types

Conditional types are used to choose between two declared types based on a conditional expression. When we used keyof with TypeScript mapped types, we mapped all the properties to the boolean type. Now, we will perform conditional type mapping to use conditional types.

In the above snippet, we have mapped the non-function properties to the boolean types. All the future changes made in the FeatureFlags type will get reflected in the Features type automatically.

Using Keyof with Utility Types

Utility types are the set of inbuilt mapped types.

In the above snippet, the Record is a utility type that returns a new type after mapping all the property keys to type T.

We can make use of the Record type to rewrite the previous FeatureOptions type.

In the above snippet, we got the same Features type using the Record type to have a set of properties and transform the Features type’s properties to a boolean type.

We can also use the keyof operator with the Pick type. This type allows you to pick single or multiple properties from an object type and generate a new type with chosen properties.

The keyof operator guarantee that the constraint is applied as only valid property names will get passed to the second parameter K .

Conclusion

  • This operator is small but can create a critical cog in the TypeScript machine.
  • When we use keyof with other tools in TypeScript, we can provide well-constrained types to enhance type safety in the code.
  • The keyof type annotation is used to take out the keys from an object.
  • Using the object.keys() method, we can retrieve key indexes and their values. Users can easily retrieve data while working on bi-enterprise applications.
  • In this article, we were able to use the keyof operator with TypeScript generics, TypeScript mapped types, Explicit keys, Index signatures, Conditional mapped types, and Utility types.
  • Hope this article has provided you with the relevant information related to the keyof keyword and its importance in the TypeScript code.

Источник

Читайте также:  Css navigation bar templates
Оцените статью