Crafting a typed function

Functions are first-class citizens in JavaScript. Since the early versions of ECMAScript, functions were the main concept to execute code and create scope. TypeScript uses the function the same way but provides additional typing features.

A function has a main signature that contains the name of this one, the list of parameters, and the return type. Parameters are defined in parentheses, as in JavaScript, but each parameter will be followed by its type using the colon syntax:

function funct1(param1: number): string { return ""; }

A function can have several parameters of a different type:

function funct2(param1: boolean, param2: string): void { }

It can also have a parameter that has more than one type using a union:

function funct3(param1: boolean | string): void { }

A function has a single return declaration but that type can use a union to allow types:

function funct4(): string | number | boolean { return ""; }

A function can have a complimentary signature to indicate to the consumer which parameters match together and with the return type. Having several function signatures for the same body is the concept of an overloaded function. When using an overloaded function, all signatures must be written from top to bottom from the most specific to the largest one. All the definition requires finishing with a semicolon expect the last one. The last signature always has a union that covers all possible types for each position. In the following code example, we specify that if the parameter is a boolean, then the function returns a string. If the parameter is a Date, then the return type is a number. The last signature contains a first parameter the union of both possible values (boolean and date) as well as a union for the return type between string and number):

function funct5(param1: boolean): string;
function funct5(param1: Date): number;
function funct5(param1: boolean | Date): string | number {
if (typeof param1 === "boolean") {
return param1 ? "Yes" : "No";
} else {
return 0;
}

}

const expectedString: string = funct5(true); // Yes
const expectedNumber: number = funct5(new Date()); // 0

A function can be anonymous. Here is an example with the fat arrow format and one example returning a Function constructor:

function returnAnAnonymousFunction(): () => number {
return () => 1;
}

function returnAnAnonymousFunction2(): Function {
return function () { return 1 };
}

A function can be a variable function or a typical function. Here are three functions set in a variable. The variable can be called by using parentheses and the required parameter. The code example shows also two ways to return data with the fat arrow format. If the code returns directly without doing any several statements, the need for curly brackets and return statement is not needed:

const variable = (message: string) => message + " world";
const variable2 = (message: string) => { return message + " world" };
const variable3 = function (message: string) { return message + " world" };

variable("Hello");

A function can have an optional parameter and a default value parameter. An optional parameter is denoted by the use of question mark after the name of the parameter. An optional parameter allows avoiding passing a value. TypeScript automatically sets the parameter to undefined:

function functWithOptional(param1?: boolean): void { }
functWithOptional();
functWithOptional(undefined);
functWithOptional(true);

Optional is different than having the variable with a union to undefined because the union requires passing the value or undefined while optional allows passing the value, undefined or nothing:

function functWithUndefined(param1: boolean | undefined): void { }
functWithUndefined(true);
functWithUndefined(undefined);

Optional can only be set after non-optional parameter. The reason is that other parameters are required but having Optional before or in the middle would make it hard to map which parameter is which. The following code example presents a case where the function does not compile because of that rule. However, it's possible to have many optional parameters:

function functWithOptional2(param1?: boolean, param2: string): void { } // Doesn't compile
function functWithOptional3(param1?: boolean, param2?: string): void { }

A function can be in a class (object-oriented is covered in a future chapter). When this happens, the syntax is different. It doesn't use the keyword function. Instead, the visibility is provided, which is public, private, or protected. TypeScript allows avoiding access modifiers, which will result in a public function. As for a class variable, the omission of the visibility uses public as default:

  class ClassFullOfFunctions {
public f1() { }
private f2(p1: number): string { return ""; }
protected f3(): void { }
f4(): boolean { return true; }
f5(): void { } // Public
}

The basis remains the same with parameters and a return type that is strongly typed. It is also possible to create a variable that holds the function inside a class as seen in this chapter. Here are three examples of a private function defined as a variable. The first one is long and very explicit. The second example doesn't define the type at the function level because it is already defined in the declaration. The last example doesn't define the type of the variable and the variable is still strongly typed because it infers its signature from the initialization:

private long: (p1: number) => string = (p1: number) => { return ""; }
private short: (p1: number) => string = (p1) => "";
private tiny = (p1: number) => "";

A function in a variable is technically called a function expression, while the more traditional function syntax is named a function statement. The usage of one or the other is the same in TypeScript than with JavaScript. Because it operates under JavaScript's law, it means that the expression function is not hoisted.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.221.175.218