Typescript Some Love-Hate Content — Type Guard, Narrowing

Author: God Q Superman
Translator: Front-end Xiaozhi
Source: medium

If you have dreams and dry goods, you can search for [Great Move to the World] on WeChat and pay attention to this Shawanzhi who is still washing dishes in the early hours of the morning.

This article GitHub https://github.com/qq449245884/xiaozhi has been included, there are complete test sites, materials and my series of articles for interviews with first-line manufacturers.

Since JavaScript itself is a weak language, it is often distressed in development because it does not know what the type of the variable is. Even if the positioning of the variable is made a little clearer by naming it, it is still difficult for us to know its type at a glance. When this variable is a object, it 's harder to know what's keyin it, so people gradually start using TypeScript as their main development tool.

I don’t know if you feel that TypeScript is particularly annoying when you are developing with TypeScript, although it is very good to know that these type checking actions can help us reduce many potential errors that may occur. Coming today Talk about how to solve this problem when we encounter this kind of problem in development.

scene one

I don't know if you have encountered this kind of problem. Today, I want to make this variable check whether it enummatches a certain value in , but TypeScript sprayed it wrong for you, like the following.

insert image description here

In fact, there are many ways to solve the above red letter. The first is to use @ts-ignoreit to make the error disappear. Of course, this method is very bad. It is equivalent to telling TypeScript not to check the following line.

insert image description here

At this time, I may think of another method. The above error message is that it malehas not been received assignby GENDERthis type, so I just force him to typethis , like this:

insert image description here

But it is still not good to write this way, it means that you are forcing the change of the variable, which makes the variable lose its flexibility. Next, we will introduce a more useful method, let us continue to read it!

Type Guard

The first thing to introduce is Type Guard . Type Guard, as its name suggests, is a type guard. Just now TypeScript will report an error because the type is different, so as long as we create a type guard, let TypeScript know that this variable will definitely enummatch value, the red letter will not appear at this time, and usually Type Guard will be written functionlike this:

const assertsIsGender = (gender: any) : gender is GENDER => {
    
    
  return Object.values(GENDER).includes(gender)
}

At this time, we can find that genderthis variable has changed from stringtype to GENDERtype, so even if I am bored and make includesanother judgment, TypeScript will not report any errors.

Here genderI assign the variable as a stringtype before assigning the value. This action is very important. If the variable type is not assigned first and then the value is assigned, the variable cannot be typechanged .

insert image description here

scene two

I don’t know if you have encountered the data returned in the API, and errors will occur because enumthe different, like the following:

insert image description here

With the above concept of Type Guard, readers at this time must know to write a functionto deal with this error message:

insert image description here

It is true that the error message is gone, but it is very genderstrange become a nevertype, and this is a type protection mechanism that Type Guard will do: Narrowing .

Type Narrowing

Narrowing translated into vernacular is type narrowing . In the world of TypeScript, each enumis basically independent and has no intersection with each other. The relationship diagram is as follows:

insert image description here

Therefore, to perform type conversion between two enums, it is easy to generate a type that may not exist. For the type that may not exist, TypeScript defines this type as never, and at this time, when we use the technique of Type Guard , TypeScript will automatically narrow the type to never typeone instead of automatically converting it to enumanother .

Of course, you may think like this if you are smart: then I just need to function returndefine another one enum, so that I can ensure that the result of my Type Guard will be type converted to the enum I want, like the following:

insert image description here

There seems to be no problem in writing this way, and the result we want has changed from type narrowing to type conversion , but this is actually a bit inconsistent with the spirit of Type Guard. After all, Type Guard does type checking instead of Type conversion, and if what we want to do is type conversion, this will also make functionthe reusability of this not high, so we will introduce a better type conversion method next.

Mapper enum

First of all, we can think about how to make type conversion reused. We might as well simplify the idea, that is, to create functiona Aconversion type to Btype , and at this time, we must use the Generics generic type in TypeScript . , like this:

const createEnumMapper = <T>(mapping: T) => (value: keyof T | null) : T[keyof T] | undefined => {
    
    
  return value === null ? undefined : mapping[value]
}

createEnumMapperThe function of this is one currying function, and the first variable passed in is the enum itself. At this time, Generics of TypeScript will know that my Tis related to enumitself.

In order for this Genericsto correctly pair the two enum mapping, we must first create a pairing objectof the enumtwo key valuelike this:


const mapper = {
  [BE_GENDER.MALE]: FE_GENDER.MALE,
  [BE_GENDER.FEMALE]: FE_GENDER.FEMALE
}

Since our above mapperis to treat enum valueas key, so we can directly convert datathe , like the following:

[External link image transfer failed, the source site may have an anti-leech mechanism, it is recommended to save the image and upload it directly (img-uaof0Gel-1645574343364)(/img/bVcXRjL)]

At this time, we can find that we have successfully BE_GENDERconverted the value of type into FE_GENDERthe value of type, and we do not need to use the concept of Type Guard.

insert image description here

Summarize

Today, I introduced the methods used to check types in TypeScript. If readers encounter similar problems in the future, they can use Type Guard to check more, instead of using them directly. @ts-ignoreOr asthese two methods, in addition to introducing type checking, also introduce As for how to perform type conversion, I hope that these methods will allow readers to use them without too many problems in the future.

I'm Shawanzhi. In the new year, let's brush together.

The bugs that may exist after the code is deployed cannot be known in real time. In order to solve these bugs afterwards, a lot of time is spent on log debugging. By the way, I recommend a useful bug monitoring tool , Fundebug .

Guess you like

Origin blog.csdn.net/qq449245884/article/details/123081580