Welcome to wechat public account: Front Reading Room

introduce

This section introduces type inference in TypeScript. That is, where and how types are inferred.

basis

In TypeScript, type inference helps provide types where they are not explicitly specified. Here’s an example

let x = 3;
Copy the code

The type of variable X is inferred to be a number. This inference occurs when initializing variables and members, setting default parameter values, and determining the return value of a function.

For the most part, type inference is straightforward. In the following sections, we’ll look at the nuances of type inference.

Best generic type

When you need to infer a type from several expressions, the types of those expressions are used to infer the most appropriate generic type. For example,

let x = [0.1.null];
Copy the code

To infer the type of X, we must consider the types of all elements. There are two options: number and NULL. The compute common type algorithm considers all candidate types and gives a type that is compatible with all candidate types.

Because the final generic type is derived from the candidate type, sometimes the candidate types share the same generic type, but no one type can be used as a type for all candidate types. Such as:

let zoo = [new Rhino(), new Elephant(), new Snake()];
Copy the code

Here, we want zoo to be inferred as Animal[], but there are no objects in this array that are of Animal type, so we cannot infer this result. To correct this, we need to specify the type explicitly when candidate types are not available:

let zoo: Animal[] = [new Rhino(), new Elephant(), new Snake()];
Copy the code

If there is no find the best general type, type inference as an associative array type, the result of the (Rhino | Elephant | Snake) [].

Context type

TypeScript type inference can also go in the opposite direction. This is called “categorizing by context.” Context-specific categorization occurs when the type of the expression is related to its location. Such as:

window.onmousedown = function(mouseEvent) {
    console.log(mouseEvent.button);  //<- Error
};
Copy the code

This example results in a type error. The TypeScript type checker uses the type of the window. onmousedown function to infer the type of the right-hand function expression. Therefore, you can infer the type of the mouseEvent parameter. If the function expression is not in the context type, the mouseEvent parameter needs to be of type ANY so that no errors are reported.

If the context type expression contains explicit type information, the context type is ignored. Rewrite the above example:

window.onmousedown = function(mouseEvent: any) {
    console.log(mouseEvent.button);  //<- Now, no error is given
};
Copy the code

This function expression is annotated with an explicit parameter type, and the context type is ignored. This way, no errors are reported, because the context type is not used here.

Contextual categorization can be used in many situations. Usually contains function arguments, the right side of assignment expressions, type assertions, object member and array literals, and return value statements. Context types are also considered candidates for the best generic type. Such as:

function createZoo() :Animal[] {
    return [new Rhino(), new Elephant(), new Snake()];
}
Copy the code

In this example, there are four candidates for the best generic type: Animal, Rhino, Elephant, and Snake. Of course, Animal would be considered the best generic type.

Welcome to wechat public account: Front Reading Room