VDone Demo VDone Demo
Home
  • Articles

    • JavaScript
  • Study Notes

    • JavaScript Tutorial
    • Professional JavaScript
    • ES6 Tutorial
    • Vue
    • React
    • TypeScript: Build Axios from Scratch
    • Git
    • TypeScript
    • JS Design Patterns
  • HTML
  • CSS
  • Technical Docs
  • GitHub Tips
  • Node.js
  • Blog Setup
  • Learning
  • Interviews
  • Miscellaneous
  • Practical Tips
  • Friends
About
Bookmarks
  • Categories
  • Tags
  • Archives
GitHub (opens new window)

Nikolay Tuzov

Backend Developer
Home
  • Articles

    • JavaScript
  • Study Notes

    • JavaScript Tutorial
    • Professional JavaScript
    • ES6 Tutorial
    • Vue
    • React
    • TypeScript: Build Axios from Scratch
    • Git
    • TypeScript
    • JS Design Patterns
  • HTML
  • CSS
  • Technical Docs
  • GitHub Tips
  • Node.js
  • Blog Setup
  • Learning
  • Interviews
  • Miscellaneous
  • Practical Tips
  • Friends
About
Bookmarks
  • Categories
  • Tags
  • Archives
GitHub (opens new window)
  • 初识 TypeScript

  • TypeScript 常用语法

    • Basic Types
    • Variable Declarations
    • Interfaces
    • Classes
    • Functions
    • Generics
    • Type Inference
      • Basics
      • Best Common Type
      • Contextual Typing
    • Advanced Types
  • ts-axios 项目初始化

  • ts-axios 基础功能实现

  • ts-axios 异常情况处理

  • ts-axios 接口扩展

  • ts-axios 拦截器实现

  • ts-axios 配置化实现

  • ts-axios 取消功能实现

  • ts-axios 更多功能实现

  • ts-axios 单元测试

  • ts-axios 部署与发布

  • 《TypeScript 从零实现 axios》
  • TypeScript 常用语法
HuangYi
2020-01-05
Contents

Type Inference

# Type Inference

This section covers type inference in TypeScript -- that is, where and how types are inferred.

# Basics

In TypeScript, where no explicit type is given, type inference is used to provide type information. For example:

let x = 3
1

The type of variable x is inferred to be number. This kind of inference occurs when initializing variables and members, setting default parameter values, and determining function return types.

In most cases, type inference is straightforward. In the following sections, we'll explore the nuances of how types are inferred.

# Best Common Type

Sometimes we need to infer a type from several expressions, and the types of those expressions are used to determine the best common type. For example:

let x = [0, 1, null]
1

To infer the type of x, we must consider the types of all elements. Here there are two candidates: number and null. The best common type algorithm considers all candidate types and selects a type that is compatible with all of them.

Since the resulting common type is chosen from the candidate types, sometimes candidates share a common structure but none of them is a supertype of all others. For example:

class Animal {
  numLegs: number
}

class Bee extends Animal {
}

class Lion extends Animal {
}

let zoo = [new Bee(), new Lion()]
1
2
3
4
5
6
7
8
9
10
11

Here, we'd like zoo to be inferred as Animal[], but since no element in the array is of type Animal, we can't infer that result. To fix this, we can explicitly declare the type we expect:

let zoo: Animal[] = [new Bee(), new Lion()]
1

If no best common type is found, the resulting inference is the union array type, (Bee | Lion)[].

# Contextual Typing

Sometimes TypeScript infers types differently through what we call "contextual typing." Contextual typing occurs when the type of an expression is implied by its location. For example:

window.onmousedown = function(mouseEvent) {
  console.log(mouseEvent.clickTime)  // Error
}
1
2
3

This example produces a type error. The TypeScript type checker uses the type of the window.onmousedown function to infer the type of the function expression on the right. Thus, it can infer the type of the mouseEvent parameter. Since mouseEvent accessed a property that doesn't exist, an error was reported.

If the contextual type expression contains explicit type information, the contextual type is ignored. Rewriting the above example:

window.onmousedown = function(mouseEvent:any) {
  console.log(mouseEvent.clickTime)  // OK
}
1
2
3

This function expression has an explicit parameter type annotation, so the contextual type is ignored. In this case there's no error, because contextual typing isn't applied.

Contextual typing is used in many situations. Common cases include function arguments, the right side of assignments, type assertions, object members, array literals, and return statements. Contextual typing also serves as a candidate for the best common type. For example:

function createZoo(): Animal[] {
  return [new Bee(), new Lion()]
}

let zoo = createZoo()
1
2
3
4
5

In this example, the best common type has 3 candidates: Animal, Bee, and Lion. Animal is selected as the best common type.

Edit (opens new window)
#TypeScript
Last Updated: 2026/03/21, 12:14:36
Generics
Advanced Types

← Generics Advanced Types→

Recent Updates
01
How I Discovered Disposable Email — A True Story
06-12
02
Animations in Grid Layout
09-15
03
Renaming a Git Branch
08-11
More Articles >
Theme by VDone | Copyright © 2026-2026 Nikolay Tuzov | MIT License | Telegram
  • Auto
  • Light Mode
  • Dark Mode
  • Reading Mode