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

Implementation of Webpack3+React16 code splitting

Project Background Recently, there is a project w...

How to manage cached pages in Vue

Table of contents Problem 1: Destruction 1. How t...

Example of viewing and modifying MySQL transaction isolation level

Check the transaction isolation level In MySQL, y...

How to decrypt Linux version information

Displaying and interpreting information about you...

MySQL full-text fuzzy search MATCH AGAINST method example

MySQL 4.x and above provide full-text search supp...

JavaScript Canvas draws dynamic wireframe effect

This article shares the specific code of JavaScri...

Linux operation and maintenance basic swap partition and lvm management tutorial

Table of contents 1. Swap partition SWAP 1.1 Crea...

MySQL transaction analysis

Transaction A transaction is a basic unit of busi...

Detailed explanation of the process of modifying Nginx files in centos7 docker

1. Install nginx in docker: It is very simple to ...

Several situations where div is covered by iframe and their solutions

Similar structures: Copy code The code is as foll...

How to redirect URL using nginx rewrite

I often need to change nginx configuration at wor...

7 ways to vertically center elements with CSS

【1】Know the width and height of the centered elem...

Using the outline-offset property in CSS to implement a plus sign

Assume there is such an initial code: <!DOCTYP...

MySQL restores data through binlog

Table of contents mysql log files binlog Binlog l...

Example of implementing QR code scanning effects with CSS3

Online Preview https://jsrun.pro/AafKp/ First loo...