The introduction

At a time when typescript is in vogue, it’s important to master some advanced uses of typescript to develop high-quality code. In the next few minutes, I’ll take a look at some advanced uses of typescript using examples. This installment looks at the typescript crossover type &.

define

The official analysis of crossover types is as official as ever!!

Cross typing is merging multiple types into one type. This allows us to superimpose existing types into a single type that contains all the required features of the type. For example, Person & Serializable & Loggable are both Person and Serializable and Loggable. This means that an object of this type has members of all three types.

Take a chestnut

Objects of type iUserInfo will have all members of both types iName and iBaseInfo.

interface iName {
  firstName: string;
  lastName: string;
}

interface iBaseInfo {
  sex: 'male' | 'female';
  age: number;
}

type iUserInfo = iName & iBaseInfo;
const user: iUserInfo = {
  firstName: 'Jack',
  lastName: 'Ma',
  sex: 'male',
  age: 40};Copy the code

Type member conflict handling

Members continue to merge when there is a type conflict, such as:

interface iProps1 {
  size: string;
}
interface iProps2 {
  size: number;
}
type iProps = iProps1 & iProps2;
let props: iProps = {
  size: 'ddd'};Copy the code

The combined iProps will look like this:

type iProps = {
  size: string & number;
};
Copy the code

Obviously, string & number does not exist, so it is equivalent to

type iProps = {
  size: never;
};
Copy the code

So the editor is red, and it’s easy to parse.

So we’ve defined a type of never, what is a type of never?

Never type

Let’s look at the parsing of official documents

The never type represents the types of values that never exist. For example, the never type is the return type of function expressions or arrow function expressions that always throw an exception or have no return value at all; Variables can also be of type never, when they are bound by type protection that is never true. The never type is a subtype of any type and can be assigned to any type; However, no type is a subtype of never or can be assigned to a type of never (except never itself). Even any cannot be assigned to never.

At first glance, it doesn’t seem to work! I also once thought so before, in fact, its effect is still very big! For example, when you have a union type:

type AllType = 'a' | 'b';
Copy the code

In switch, TS is a discriminated union:

function handleValue(val: AllType) {
  switch (val) {
    case 'a':
      // val Narrows to 'a'
      break;
    case 'b':
      // val Narrows to 'b'
      break;
    default:
      // val Narrows here to never
      const exhaustiveCheck: never = val;
      break; }}Copy the code

Note that in default we assign val narrowed to never to a variable explicitly declared never. If everything is logically correct, then this should compile. But suppose you later change the type of AllType:

type AllType = 'a' | 'b' | 'c';
Copy the code

If you forget to add logic to handleValue for ‘c’, then val will be narrowed to ‘c’ in default, making it impossible to assign to never and an error will occur.

@Author: WaterMan