Detailed explanation of type protection in TypeScript

Detailed explanation of type protection in TypeScript

Overview

When using union types in TypeScript, you often encounter this awkward situation:

interface Bird {
  	// Unique method fly();
  	// Public method layEggs();
}

interface Fish {
  	// Unique method swim();
  	// Public method layEggs();
}

function getSmallPet(): Fish | Bird {
    // ...
}

let pet = getSmallPet();
pet.layEggs(); // normal pet.swim(); // ts error

As shown above, the getSmallPet function can return both Fish and Bird type objects. Since the type of the returned object is uncertain, everything works fine when using methods shared by union type objects, but ts will report an error when using methods unique to each union type object.

So how to solve this problem? The most brutal method is of course to convert the union type to any, but this method is not worth advocating, after all, we are writing TypeScript instead of AnyScript.

At this point, we use today's protagonist - type protection, which makes a shining debut and can perfectly solve this problem.

Kong Yiji once said that there are four ways to write fennel beans. Similarly, there are four ways to write type protection.

Type Assertions

Type assertion is the most commonly used type protection method, which directly specifies the type. Since most of the types recognized in TypeScript are calculated by TypeScript's automatic type inference, the problem mentioned above will occur, that is, TypeScript does not know what the specific object type is, so it is not sure whether there are unique methods for each union type.

When you use type assertions to specify types directly, it is equivalent to turning on TypeScript's God mode, so you can directly know the specific type is the one in the union type. At this time, using the unique method of the object is in line with TypeScript's inference.

interface Bird {
  // Unique method fly();
  // Public method layEggs();
}

interface Fish {
  // Unique method swim();
  // Public method layEggs();
}

function getSmallPet(): Fish | Bird {
  // ...
}

let pet = getSmallPet();
pet.layEggs(); // Normal // Judge by duck type if ((pet as Bird).fly) {
  // Type assertion (pet as Bird).fly()
} else {
  // Type assertion (pet as Fish).swim()
}

If you think that type assertion through as is not sophisticated enough, you can also use the generic type writing method, that is:

let pet = getSmallPet();
pet.layEggs(); // Normal // Judge by duck type if ((<Bird>pet).fly) {
  (<Bird>pet).fly()
} else {
  (<Fish>pet).swim()
}

Tips: Friendly reminder, although using generic type writing for type assertion seems more advanced, due to the grammatical ambiguity in tsx, for the sake of uniformity, it is recommended to use the as method for type assertion.

in syntax

In js, we often use the in syntax to determine whether a specified property is in the specified object or its prototype chain.

Similarly, in TypeScript, we can confirm the object type in this way.

interface Bird {
  // Unique method fly();
  // Public method layEggs();
}

interface Fish {
  // Unique method swim();
  // Public method layEggs();
}

function getSmallPet(): Fish | Bird {
  // ...
}

let pet = getSmallPet();
pet.layEggs(); // normal // use in syntax for type protection if ('fly' in pet) {
  pet.fly()
} else {
  pet.swim()
}

The principle is the same as type assertion, which guides TypeScript type inference and determines the object type.

instanceof syntax

When class is used instead of interface in the union type, instanceof syntax comes in handy. The instanceof syntax can be used to distinguish different class types.

class Bird {
  // Unique method fly() {};
  // Public method layEggs() {};
}

class Fish {
  // Unique method swim() {};
  // Public method layEggs() {};
}

function getSmallPet(): Fish | Bird {
  // ...
}

let pet = getSmallPet();
pet.layEggs(); // Normal // Use in syntax if (pet instanceof Bird) {
  pet.fly()
} else {
  pet.swim()
}

typeof syntax

The typeof syntax is different from the in syntax and the instanceof syntax. Both the in syntax and the instanceof syntax are used to guide type inference to perform different object type inferences, while the typeof syntax is often used to infer basic types (or to use basic types and object types in combination).

In short, use typeof when you can distinguish between the different types in a union type.

function getSmallPet(): number | string {
  // ...
}

let pet = getSmallPet();
if (typeof pet === 'number') {
  pet++
} else {
  pet = Number(pet) + 1
}

Summarize

Just as the essence of the four ways of writing fennel beans is still fennel beans, the essence of the four ways of writing type protection is also the same, that is, guiding the type inference in TypeScript to turn the multiple-choice questions of type inference into single-choice questions, which is the essence of type protection.

The above is a detailed explanation of type protection in TypeScript. For more information about TypeScript type protection, please pay attention to other related articles on 123WORDPRESS.COM!

You may also be interested in:
  • TypeScript Enumeration Type
  • Introduction to TypeScript basic types
  • Explain TypeScript enumeration types in detail
  • How to apply TypeScript classes in Vue projects
  • A brief discussion on TypeScript's type protection mechanism
  • Classes in TypeScript

<<:  Database backup in docker environment (postgresql, mysql) example code

>>:  MySQL Index Detailed Explanation

Recommend

Detailed tutorial for downloading, installing and configuring MySQL 5.7.27

Table of contents 1. Download steps 2. Configure ...

How to completely delete the MySQL 8.0 service under Linux

Before reading this article, it is best to have a...

Steps to customize icon in Vue

ant-design-vue customizes the use of Ali iconfont...

About the configuration problem of MyBatis connecting to MySql8.0 version

When learning mybatis, I encountered an error, th...

Detailed explanation of MySQL master-slave database construction method

This article describes how to build a MySQL maste...

React event binding details

Table of contents Class component event binding F...

Vue uniapp realizes the segmenter effect

This article shares the specific code of vue unia...

Avoid abusing this to read data in data in Vue

Table of contents Preface 1. The process of using...

10 key differences between HTML5 and HTML4

HTML5 is the next version of the HTML standard. M...

Docker installation and deployment of Net Core implementation process analysis

1. Docker installation and settings #Install Cent...

WeChat applet tab left and right sliding switch function implementation code

Effect picture: 1. Introduction Your own applet n...

Example code for implementing hexagonal borders with CSS3

The outermost boxF rotates 120 degrees, the secon...