Static Checking of Operations

Disallowing Calling Uncallable Values

Calling an uncallable value in JavaScript at runtime throws Uncaught TypeError.

// JavaScript
42() // Uncaught TypeError: 42 is not a function.

const witcher = { getName: () => 'Geralt' }
witcher.name() // Uncaught TypeError: witcher.name is not a function.

TypeScript allows preventing such errors pre-runtime through static code analysis.

const witcher = { name: 'Geralt' }
witcher.name() // TS: This expression is not callable. Type 'String' has no call signatures.

Disallowing Accessing Non-Existing Properties

Accessing a non-existing property of a non-null object in JavaScript does not throw an error and returns undefined.

// JavaScript
const witcher = { name: 'Geralt' }
witcher.firstName // undefined

TypeScript can prevent pre-runtime from trying to access a non-existing property of a non-null object.

// TypeScript
const witcher = { name: 'Geralt' }
witcher.firstName // TS: Property 'firstName' does not exist on type '{ name: string; }'.

Further, trying to access a property of a value that is undefined or null throws Uncaught TypeError: Cannot read properties of undefined / null.

// JavaScript
const empty = null
empty.some // Uncaught TypeError: Cannot read properties of null (reading 'some').

TypeScript can prevent pre-runtime from trying to access a property of undefined or null.

// TypeScript
const empty: null = null
empty.some // TS: Object is possibly 'null'.

Disallowing Nonsensical Arithmetic Operations

In JavaScript, some nonsensical arithmetic operations do not throw an error but still might have unintended consequences.

For example, dividing a number by a string in JavaScript does not throw an error but might return NaN.

// JavaScript
42 / 'forty two' // => NaN

TypeScript can prevent pre-runtime from such nonsensical arithmetic operations.

// TypeScript
42 / 'forty two' // => The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.