Typescript infers the Data type of the variable, even if there is no type is declared. We call this Type Inference. The variables in the typescript tutorial show the various ways to declare a variable. We can declare the variable without type annotation. In such a circumstance, the Typescript makes an attempt to infer the type of the variable.
Table of Contents
Type Inference
Typescript tries to infer the type if you do not specify one, by determining the type of the initial value assigned to it or based on its usage.
There are two ways types are inferred in Typescript. One is explicit and the other one is implicit
Explicit Typing is when we just declare the variable with the types.
1 2 3 4 | let numVar: number; let numbers: number[] = [1,2,3] |
In Implicit typing, we do not declare the types. Typescript makes an attempt to deduce the type from its usage.
1 2 3 4 5 6 7 | let numVar=100; // No Data type is specifed. The typescript will // Infer the variable as number numVar = "Hello World"; //Error is thrown here console.log(numVar); |
In the above code. we declare a variable without type but assign an initial value to it.
The Typescript infers or determines that the initial value is a number, hence infers the numVar
as the number.
In the next line, we try to assign a string to the numVar
and the typescript compiler flags this code as an error
1 2 3 | error TS2322: Type '"Hello World"' is not assignable to type 'number' |
The above is one of the many ways in which typescript makes an attempt to infer the type when the type information is not provided in the variable declaration.
Variable declaration
The types of variables are inferred when an initial value is assigned to them. We looked at it in the previous example
1 2 3 | var numVar=100; |
If no implicit type is specified or value is assigned, then typescripts infer it as any
.
1 2 3 4 5 | let x // This is inferred as any x = 100 // No Error here x = "Hi" // No Error here either |
Expressions
The type is inferred from the expression’s result.
1 2 3 4 5 | numVar1=100; numVar2=200; let numVar3 = numVar1+numVar2 //numvar3 is inferred number |
1 2 3 4 | let x="Hello"; let y=x; // y is inferred as string; |
Function Parameter Default Values
The types of function parameters are inferred, when the default values are set for parameters
Example
1 2 3 4 5 6 | function sum(a=10, b=10) { //a & b are inferred as numbers a="test" //Error thrown here return a+b } |
Function Return type
The Typescript infers the return type of function based on the return value.
Example
1 2 3 4 5 6 7 | function add(a=10, b=10) { //a & b are inferred as numbers return a+b } let x=add(); //x is inferred as number. |
In the above example, the Typescript infers the return type of add
function as a number
. And when we assign it to the x
variable, then it is also inferred as a number
.
Objects
The Type inference for the complex data types like objects works in similar ways. The types of properties of the objects are infrared just like variables
The Type inference also works for complex data types like objects, arrays, etc
Example
1 2 3 4 5 6 7 | let employee = { code: 123, name: "Sachin Tendulkar" }; employee.code = "hello"; // Error '"hello"' is not assignable to type 'number' |
Example
1 2 3 4 5 6 | let employee = {} // inferred as {} employee['code'] = 123 // OK employee['name'] = "Sachin Tendulkar" // OK employee.code = 100 // Error Property 'code' does not exist on type '{}' |
Arrays
Similarly, the data type of the array is based on the initial element assigned to it.
Example
1 2 3 4 5 6 7 | let students = ['sachin', 'rahul', 'saurav']; // type of students is string[] let grades = [95,98 ,96]; // type of grades is number[] grades[0]=null; //error => Type 'null' is not assignable to type 'number'.ts(23 |
In the following example, the array has a mixed type number and a null value. The compiler determines the type as a union type of number & null. We can assign a number or null to any element of the array. The other data types result in compiler errors.
Example
1 2 3 4 5 6 7 8 9 | let grades = [0, 1, null]; // type of grades is (number | null) [] grades [2]="test"; // Error Error: type '"test"' is not assignable to type 'number | null' grades [1]=null; //allowed becuase type is number|null grades [1]=0; //alowed |
Example
Here is another example of a mixed type of string & number. You can assign only string and number values to the array. Any other data type results in a compiler error.
1 2 3 4 5 6 7 | let grades = [0, 1, "A"]; // type of grades is (number | string) [] grades [2]="test"; // ok grades [1]=null; //Error null is not allowed grades [2]=0; //alowed |
Any is the default type
What if the Compiler fails to infer the type of the variable?. The Typescript assigns the type any
to it.
noImplicitAny
Typescript will do its best to infer. But there are circumstances where inferring type as any
may result in unexpected errors. We can make typescript throw an error whenever that happens using the "noImplicitAny": true
option tsconfig.json
.
Example:
Open the tsconfig.json
and add the following.
1 2 3 4 5 6 7 8 | { "compilerOptions": { "noImplicitAny": true, }, |
In the following example, variables x & y are not annotated with any type. Hence it is unclear here, what should be the allowed values. The TypeScript infers them as any
, but a compiler error results if the above flag is set to true.
1 2 3 4 5 | function sum(x,y) { // Error: x has an implicit `any` type return x+y; } |
Summary
Typescript inference works try to infer the type if you do not specify one, by determining the type of the initial value assigned to it.
let employee = {} // inferred as {}
employee[‘code’] = 123 // OK
employee[‘name’] = “Sachin Tendulkar” // OK
employee.code = 100
2nd and 3rd line also giving errro
Element implicitly has an ‘any’ type because expression of type ‘”code”‘ can’t be used to index type ‘{}’.
Property ‘code’ does not exist on type ‘{}’.
Element implicitly has an ‘any’ type because expression of type ‘”name”‘ can’t be used to index type ‘{}’.
Property ‘name’ does not exist on type ‘{}’.
Property ‘code’ does not exist on type ‘{}’.
let employee = {} // inferred as {}
employee[‘code’] = 123 // OK
employee[‘name’] = “Sachin Tendulkar” // OK
employee.code = 100
giving error
Element implicitly has an ‘any’ type because expression of type ‘”code”‘ can’t be used to index type ‘{}’.
Property ‘code’ does not exist on type ‘{}’.
Element implicitly has an ‘any’ type because expression of type ‘”name”‘ can’t be used to index type ‘{}’.
Property ‘name’ does not exist on type ‘{}’.
Property ‘code’ does not exist on type ‘{}’.
This website is pure gold for all typescript students….. wow!! so easy to grasp and understand!!! Recommend people to spend a week going thru all the typescript articles…. fantastic team of authors/writers here….