How to limit the value range of object keys in TypeScript

How to limit the value range of object keys in TypeScript

When we use TypeScript, we want to use the type system it provides to constrain all aspects of the code, and the key values ​​of objects are no exception.

For example, we have an object that stores the names of people in each grade, and the type might look like this:

type Students = Record<string, string[]>;

Of course, the data looks like this:

const students: Students = {
  Freshman: ["David", "John"],
  sophomore: [],
  Junior: ["Lily"],
  Senior: ["Tom"],
};

Limit object keys to enumerations

The problem with the above data type is that there are only a limited number of possible values ​​for grade, but attributes can be added to the object arbitrarily, which makes the data seem impure.

So we add a new enumeration to list the possible values:

export enum Grade {
  Freshman,
  sophomore,
  Junior,
  Senior,
}

Now, just restrict the object's keys to the above enumeration.

- type Students = Record<string, string[]>;
+ type Students = Record<Grade, string[]>;

Our data can be written like this:

const students: Students = {
  [Grade.Freshman]: ["David", "John"],
  [Grade.sophomore]: [],
  [Grade.Junior]: ["Lily"],
  [Grade.Senior]: ["Tom"],
  // ❌ Object literal may only specify known properties, and 'blah' does not exist in type 'Students'.ts(2322)
  blah: ["some one"],
};

In this way, the range of key names on the object is limited. You can see that an error will be reported if a key outside the enumeration is added.

More semantic enumeration values

However, the above approach is still inappropriate, because the enumeration value defaults to a number starting from 0, so it is not semantic enough as a key value, which is reflected when accessing the properties of the object:

Let's fix our enum to use more semantic text as its value:

export enum Grade {
  Freshman = "Freshman",
  sophomore = "sophomore",
  Junior = "Junior",
  Senior = "Senior",
}

Now when you use the enumeration again, the numbers you get are no longer meaningless.

If you want, the enumeration value can also be Chinese,

export enum Grade {
  Freshman = "Freshman",
  sophomore = "Sophomore",
  Junior = "Junior girl",
  Senior = "Senior driver",
}

There is no problem when using:

Key value optional

There is another problem with the above type definition, that is, it requires that the object contains all the values ​​in the enumeration when used. For example, there is no one in the grade of sophomore , so you can not write it, but it will report an error.

// ❌ Property 'sophomore' is missing in type '{ Freshman: string[]; Junior: string[]; Senior: string[]; }' but required in type 'Students'.ts(2741)
const students: Students = {
  [Grade.Freshman]: ["David", "John"],
  // [Grade.sophomore]: [],
  [Grade.Junior]: ["Lily"],
  [Grade.Senior]: ["Tom"],
};

Therefore, the optimization type is optional:

type Students = Partial<Record<Grade, string[]>>;

If the optional values ​​are not defined by an enumeration but come from an array,

const grades = ["Freshman", "sophomore", "Junior", "Senior"];

This means we need to extract the values ​​in the array into a union type.

First, use const assertions to convert the array to a tuple type.

const grades = <const>["Freshman", "sophomore", "Junior", "Senior"];

Then use typeof and Lookup Types to get the final union type:

// Actually type Keys = "Freshman" | "sophomore" | "Junior" | "Senior"
type Keys = typeof grades[number];

Finally, the data type and data can be written as:

type Students = Partial<Record<Keys, string[]>>;

const students: Students = {
  Freshman: ["David", "John"],
  Junior: ["Lily"],
  Senior: ["Tom"],
};

Note that in this form, the object key has no syntactic association with the elements in the original array, that is, the editor's "jump definition" is unavailable.

Try to keep the code connected to show the role of TypeScript, so operations like this that only have type constraints but cannot establish connections are not recommended.

Related resources

const assertions

keyof and Lookup Types

The text was updated successfully, but these errors were encountered:

The above is the details of limiting the value range of object key names in TypeScript. For more information about limiting the value range of object key names in TypeScript, please pay attention to other related articles on 123WORDPRESS.COM!

You may also be interested in:
  • In-depth understanding of the use of the infer keyword in typescript
  • Why TypeScript's Enum is problematic
  • A tutorial on how to install, use, and automatically compile TypeScript
  • Vue's new partner TypeScript quick start practice record
  • Explain TypeScript mapped types and better literal type inference
  • A brief discussion of 3 new features worth noting in TypeScript 3.7
  • Detailed explanation of TypeScript 2.0 marked union types
  • TypeScript function definition and use case tutorial

<<:  MySQL 5.6.15 installation and configuration method graphic tutorial under Windows 8

>>:  How to install PostgreSQL and PostGIS using yum on CentOS7

Recommend

Tips for data statistics in MySQL

As a commonly used database, MySQL requires a lot...

In-depth analysis of Flex layout in CSS3

The Flexbox layout module aims to provide a more ...

Write a publish-subscribe model with JS

Table of contents 1. Scene introduction 2 Code Op...

Detailed graphic tutorial on installing centos7 virtual machine in Virtualbox

1. Download centos7 Download address: https://mir...

A pitfall and solution of using fileReader

Table of contents A pitfall about fileReader File...

IE6 BUG and fix is ​​a preventive strategy

Original article: Ultimate IE6 Cheatsheet: How To...

Java uses Apache.POI to export HSSFWorkbook to Excel

Use HSSFWorkbook in Apache.POI to export to Excel...

Install mysql offline using rpm under centos 6.4

Use the rpm installation package to install mysql...

Some parameter descriptions of text input boxes in web design

In general guestbooks, forums and other places, t...

Nginx service 500: Internal Server Error one of the reasons

500 (Internal Server Error) The server encountere...

The simplest form implementation of Flexbox layout

Flexible layout (Flexbox) is becoming increasingl...

Examples of using MySQL pessimistic locking and optimistic locking

Pessimistic Lock Pessimistic lock, considers the ...

Based on the special characters in the URL escape encoding

Table of contents Special characters in URLs URL ...

Mac+IDEA+Tomcat configuration steps

Table of contents 1. Download 2. Installation and...

How to implement second-level scheduled tasks with Linux Crontab Shell script

1. Write Shell script crontab.sh #!/bin/bash step...