Let’s do some evening snacks on TypeScript’s type inference strategy
As those familiar with TypeScript know, TS has a type inference system to help reduce unnecessary type declarations. Even with pure JS code, TS can automatically give each variable a default type through the type inference system.
Do you know the type inference results of the following four quantities A, B, C. prop and D.prop?
const a = 'a';
let b = 'a';
const c = {
prop: 'a'
};
class D {
static prop = 'a'
}
Copy the code
They all look the same? What happens if you use them to assign values to the following variables?
type Abc = 'a' | 'b' | 'c';
const a1: Abc = a;
const b1: Abc = b; // error!
const c1: Abc = c.prop; // error!
const d1: Abc = D.prop; // error!
Copy the code
You can find that the assignment statement except a1, all the other assignment statements are wrong!
The reason is that, except for variable A, which is inferred as single-valued type ‘a’, b, c.prop, and d. prop are inferred as strings
From the range of types string > Abc > ‘a’
So the assignment of a1 is true, and the other assignments are false.
Why is TS’s inference different for seemingly similar cases?
The root reason is that TS gives different type inferences depending on whether a value is likely to be modified in subsequent logic:
- To have aSubject to modificationTS adopts a looser type inference strategy, that is, the values described above
b
.c.prop
.D.prop
It is inferred to be relatively broadstring
Type, which gives greater flexibility to possible future assignments - forIt cannot be reassignedTS uses a more rigorous type inference strategy, namely the above
a
Inferred to be single-valued'a'
So that the futurea
There is less chance of type checking errors when assigning to other variables
Different starting points and situations result in two different types of inference strategies.
Finally, with the above strategy understood, let’s make a change to D to verify the inference logic of TS:
class D2 {
static readonly prop = 'a';
}
const d2: Abc = D2.prop; // No more error this time!
Copy the code
The addition of the readonly keyword indicates that the prop field is immutable, triggering a stricter inference policy that allows D.prop to be inferred as a single-valued type ‘A’
Further reading
Improved Inference for Literal Types in TypeScript