Understanding Record type in Typescript

In TypeScript, the Record utility type constructs an object type with set keys and corresponding value types. The syntax is Record<Keys,Type>. Here, Keys can be a union of literal types, and Type is the type of value the keys represent.

Understanding the Record Type with an Example

Have a look at the code snippet below with full of features:

type User = {
  email: string;
  password: string;
};

type AdminUser = User & {
  admin: boolean;
}

type OnlyMySelectedUsers = '1234-1829-1111-efgh' | 'asdf1234';

// const users: Record<string, User | AdminUser> = { // any string as ID
const users: Record<OnlyMySelectedUsers, User | AdminUser> = {
  '1234-1829-1111-abcd': {
    email: '[email protected]',
    password: '12345678',
  },
  '1234-1829-1111-efgh': {
    email: '[email protected]',
    password: '12345678',
  },
  'asdf1234': {
    email: '[email protected]',
    password: '12345678',
    admin: true,
  }
};

console.log(users['1234-1829-1111-abcd'].email); // not found
console.log(users['1234-1829-1111-efgh'].email); // [email protected]

In the example above, Record<OnlyMySelectedUsers, User | AdminUser> creates a type that accepts only objects whose keys are restricted to the values '1234-1829-1111-efgh' and 'asdf1234' (as defined by the OnlyMySelectedUsers type), and the values of those keys must be either User or AdminUser objects. User and AdminUser are object types that define the form of a user and an admin user, respectively. OnlyMySelectedUsers is a string literal type that takes only two distinct values. Record<OnlyMySelectedUsers, User | AdminUser> means "an object whose keys are the string literals defined by OnlyMySelectedUsers and whose values are either User or AdminUser objects".
This ensures that the Users object can only have properties with these set keys and values that adhere to the User or AdminUser structure. TypeScript would throw an error if you tried to add an unrecognized property name or assign an object of the wrong shape to a property.
In the code provided, you can see that there is no property with the key '1234-1829-1111-abcd' in Users, so the console.log statement that tries to access the email value of this key returns undefined.
On the other hand, the console.log statement that accesses the email for '1234-1829-1111-efgh' correctly returns [email protected] because this key exists in the Users object.

Conclusion

Understanding TypeScript's Record type opens the door to a whole new way of looking at data structures. It gives your code a solid foundation and adds an extra layer of safety and predictability, improving the maintainability of your code.