Static Type Checking of Functions

Unrestricted Function Argument Value Types in JavaScript

In JavaScript calling a function with arguments not congruent with defined function parameters is not considered an error.

function add(a, b) {
  return a + b
}
add(1, 2) // => 3
add('1', '2') // => '12'
add() // => NaN

Passing arguments of non-number values or not passing them at all is not considered an error by JavaScript and hence no error is thrown. Still, the function does not work as intended when non-number arguments are passed.

Further, an error might still occur when a function body is not as lenient as in the case of the add function.

function getCapitalizedName(person) {
  return person.name.charAt(0).toUpperCase() + person.name.slice(1)
}

getCapitalizedName({ name: 'joe' }) // 'Joe'
getCapitalizedName({ firstName: 'joe' }) // Uncaught TypeError: Cannot read properties of undefined (reading 'charAt').
getCapitalizedName() // Uncaught TypeError: Cannot read properties of undefined (reading 'name').

Restricting Function Argument Value Types in TypeScript

In TypeScript, it is possible to define function parameters in a way restricting the types of values allowed to be passed as arguments at the function call.

function add(a: number, b: number) {
  return a + b
}

add(1, 2) // 3
add('1', '2') // TS: Argument of type 'string' is not assignable to parameter of type 'number'.
add() // TS: Expected 2 arguments, but got 0.

Such static code checking of function argument values by TypeScript allows catching many bugs even before the program's runtime.

Function Return Values in JavaScript

All functions - unless interrupted or running indefinitely - return a value in JavaScript.

A function in JavaScript called without the new keyword can return:

  • a specific value explicitly by using the keyword return appended with the value,

  • undefined implicitly by using the keyword return with no value appended, or

  • undefined implicitly when the keyword return is omitted altogether.

function foo() {
  return 42
}
foo() // => 42

function bar() {
  return
}
bar() // => undefined

function qux() {}
qux() // => undefined

Further, a function called with the new keyword implicitly returns an object constructed through calling that function.

function user(name) {
  this.name = name
}
new user('Geralt') // => userĀ {name: 'Geralt'}

In JavaScript, it is not possible to restrict a function return value to be of a specific type.

Restring Function Return Value Types in TypeScript

TypeScript allows restricting the allowed type to be returned by a function.

To restrict a function return type follow the function parameters with : and the specified type.

function add(a: number, b: number): number {
  return `Adding ${a} and ${b} gives ${a+b}.` // TS: Type 'string' is not assignable to type 'number'.
}

function add(a: number, b: number): number {
  return a + b // OK.
}

const getCapitalizedName = (person: { name: string }): string => {
  return person // TS: Type '{ name: string; }' is not assignable to type 'string'.
}

const getCapitalizedName = (person: { name: string }): string => {
  return person.name.charAt(0).toUpperCase() + person.name.slice(1) // OK.
}