Type Inference in typescript

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.

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.

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.

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

error TS2322: Type '"Hello World"' is not assignable to type 'number'
Example of Type Inference in Typescript
Example of Type Inference in Typescript. The compiler infers the type and throws an error right away

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

var numVar=100; 

If no implicit type is specified or value is assigned, then typescripts infer it as any.

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.

numVar1=100;
numVar2=200;
let numVar3 = numVar1+numVar2    //numvar3 is inferred number
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

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

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

let employee = {
    code: 123,
    name: "Sachin Tendulkar"
};
employee.code = "hello"; // Error '"hello"' is not assignable to type 'number'

Example

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

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

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.

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.

{
    "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.

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.

3 thoughts on “Type Inference in typescript”

  1. 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 ‘{}’.

  2. 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 ‘{}’.

  3. 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….

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Scroll to Top