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.