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

How to download excel stream files and set download file name in vue

Table of contents Overview 1. Download via URL 2....

Detailed explanation of HTML basics (Part 1)

1. Understand the WEB Web pages are mainly compos...

The difference between Input's size and maxlength attributes

I recently used the input size and maxlength attri...

Solution to the problem "Table mysql.plugin doesn't exist" when deploying MySQL

Today I deployed the free-installation version of...

Native JS object-oriented typing game

This article shares the specific code of JS objec...

Install redis and MySQL on CentOS

1|0MySQL (MariaDB) 1|11. Description MariaDB data...

Solve the installation problem of mysql8.0.19 winx64 version

MySQL is an open source, small relational databas...

Tutorial on Migrating Projects from MYSQL to MARIADB

Prepare the database (MySQL). If you already have...

An example of implementing a simple finger click animation with CSS3 Animation

This article mainly introduces an example of impl...

How to use vue-cli to create a project and package it with webpack

1. Prepare the environment (download nodejs and s...

Getting Started Tutorial on Using TS (TypeScript) in Vue Project

Table of contents 1. Introducing Typescript 2. Co...

HTML solves the problem of invalid table width setting

If you set the table-layer:fixed style for a tabl...

Add unlimited fonts to your website with Google Web Fonts

For a long time, website development was hampered...

Do designers need to learn to code?

Often, after a web design is completed, the desig...