Overloads and Callbacks

Overloads and Callbacks Don’t write separate overloads that differ only on callback arity: /* WRONG */ declare function beforeAll(action: () => void, timeout?: number): void; declare function beforeAll(action: (done: DoneFn) => void, timeout?: number): void; Do write a single overload using the maximum arity: /* OK */ declare function beforeAll(action: (done: DoneFn) => void, timeout?: number): void; Why: It’s always legal for a callback to disregard a parameter, so there’s no need f

Overloads

Overloads JavaScript is inherently a very dynamic language. It’s not uncommon for a single JavaScript function to return different types of objects based on the shape of the arguments passed in. let suits = ["hearts", "spades", "clubs", "diamonds"]; function pickCard(x): any { // Check to see if we're working with an object/array // if so, they gave us the deck and we'll pick the card if (typeof x == "object") { let pickedCard = Math.floor(Math.random() * x.length); return picked

Overloaded Functions

Overloaded Functions Documentation The getWidget function accepts a number and returns a Widget, or accepts a string and returns a Widget array. Code let x: Widget = getWidget(43); let arr: Widget[] = getWidget("all of them"); Declaration declare function getWidget(n: number): Widget; declare function getWidget(s: string): Widget[];

Organizing Types

Organizing Types Documentation The greeter object can log to a file or display an alert. You can provide LogOptions to .log(...) and alert options to .alert(...) Code const g = new Greeter("Hello"); g.log({ verbose: true }); g.alert({ modal: false, title: "Current Greeting" }); Declaration Use namespaces to organize types. declare namespace GreetingLib { interface LogOptions { verbose?: boolean; } interface AlertOptions { modal: boolean; title?: string; color?: string;

Ordering

Ordering Don’t put more general overloads before more specific overloads: /* WRONG */ declare function fn(x: any): any; declare function fn(x: HTMLElement): number; declare function fn(x: HTMLDivElement): string; var myElem: HTMLDivElement; var x = fn(myElem); // x: any, wat? Do sort overloads by putting the more general signatures after more specific signatures: /* OK */ declare function fn(x: HTMLDivElement): string; declare function fn(x: HTMLElement): number; declare function fn(x: any):

Optional Properties

Optional Properties Not all properties of an interface may be required. Some exist under certain conditions or may not be there at all. These optional properties are popular when creating patterns like “option bags” where you pass an object to a function that only has a couple of properties filled in. Here’s an example of this pattern: interface SquareConfig { color?: string; width?: number; } function createSquare(config: SquareConfig): {color: string; area: number} { let newSquare = {c

Optional Parameters in Callbacks

Optional Parameters in Callbacks Don’t use optional parameters in callbacks unless you really mean it: /* WRONG */ interface Fetcher { getObject(done: (data: any, elapsedTime?: number) => void): void; } This has a very specific meaning: the done callback might be invoked with 1 argument or might be invoked with 2 arguments. The author probably intended to say that the callback might not care about the elapsedTime parameter, but there’s no need to make the parameter optional to accomplish

Optional Parameters and Rest Parameters

Optional Parameters and Rest Parameters When comparing functions for compatibility, optional and required parameters are interchangeable. Extra optional parameters of the source type are not an error, and optional parameters of the target type without corresponding parameters in the target type are not an error. When a function has a rest parameter, it is treated as if it were an infinite series of optional parameters. This is unsound from a type system perspective, but from a runtime point of

Optional and Default Parameters

Optional and Default Parameters In TypeScript, every parameter is assumed to be required by the function. This doesn’t mean that it can’t be given null or undefined, but rather, when the function is called the compiler will check that the user has provided a value for each parameter. The compiler also assumes that these parameters are the only parameters that will be passed to the function. In short, the number of arguments given to a function has to match the number of parameters the function

Objects with Properties

Objects with Properties Documentation The global variable myLib has a function makeGreeting for creating greetings, and a property numberOfGreetings indicating the number of greetings made so far. Code let result = myLib.makeGreeting("hello, world"); console.log("The computed greeting is:" + result); let count = myLib.numberOfGreetings; Declaration Use declare namespace to describe types or values accessed by dotted notation. declare namespace myLib { function makeGreeting(s: string): str