Type assertions

Type assertions Sometimes you’ll end up in a situation where you’ll know more about a value than TypeScript does. Usually this will happen when you know the type of some entity could be more specific than its current type. Type assertions are a way to tell the compiler “trust me, I know what I’m doing.” A type assertion is like a type cast in other languages, but performs no special checking or restructuring of data. It has no runtime impact, and is used purely by the compiler. TypeScript assum

Best common type

Best common type When a type inference is made from several expressions, the types of those expressions are used to calculate a “best common type”. For example, let x = [0, 1, null]; To infer the type of x in the example above, we must consider the type of each array element. Here we are given two choices for the type of the array: number and null. The best common type algorithm considers each candidate type, and picks the type that is compatible with all the other candidates. Because the best

Private and protected members in classes

Private and protected members in classes Private and protected members in a class affect their compatibility. When an instance of a class is checked for compatibility, if the instance contains a private member, then the target type must also contain a private member that originated from the same class. Likewise, the same applies for an instance with a protected member. This allows a class to be assignment compatible with its super class, but not with classes from a different inheritance hierarc

Consuming

Consuming From there you’ll be able to use lodash in your TypeScript code with no fuss. This works for both modules and global code. For example, once you’ve npm install-ed your type declarations, you can use imports and write import * as _ from "lodash"; _.padStart("Hello TypeScript!", 20, " "); or if you’re not using modules, you can just use the global variable _. _.padStart("Hello TypeScript!", 20, " ");

Namespaced Validators

Namespaced Validators namespace Validation { export interface StringValidator { isAcceptable(s: string): boolean; } const lettersRegexp = /^[A-Za-z]+$/; const numberRegexp = /^[0-9]+$/; export class LettersOnlyValidator implements StringValidator { isAcceptable(s: string) { return lettersRegexp.test(s); } } export class ZipCodeValidator implements StringValidator { isAcceptable(s: string) { return s.length === 5 && numberRegexp.test(s); }

Setting up your Directories

Setting up your Directories If you’re writing in plain JavaScript, it’s likely that you’re running your JavaScript directly, where your .js files in a src, lib, or dist directory, and then ran as desired. If that’s the case, the files that you’ve written are going to used as inputs to TypeScript, and you’ll run the outputs it produces. During our JS to TS migration, we’ll need to separate our input files to prevent TypeScript from overwriting them. If your output files need to reside in a speci

Modular Libraries

Modular Libraries Some libraries only work in a module loader environment. For example, because express only works in Node.js and must be loaded using the CommonJS require function. ECMAScript 2015 (also known as ES2015, ECMAScript 6, and ES6), CommonJS, and RequireJS have similar notions of importing a module. In JavaScript CommonJS (Node.js), for example, you would write var fs = require("fs"); In TypeScript or ES6, the import keyword serves the same purpose: import fs = require("fs"); You’

typeof type guards

typeof type guards Let’s go back and write the code for the version of padLeft that uses union types. We could write it with type predicates as follows: function isNumber(x: any): x is number { return typeof x === "number"; } function isString(x: any): x is string { return typeof x === "string"; } function padLeft(value: string, padding: string | number) { if (isNumber(padding)) { return Array(padding + 1).join(" ") + value; } if (isString(padding)) { return padding + value

Intersection Types

Intersection Types An intersection type combines multiple types into one. This allows you to add together existing types to get a single type that has all the features you need. For example, Person & Serializable & Loggable is a Person and Serializable and Loggable. That means an object of this type will have all members of all three types. You will mostly see intersection types used for mixins and other concepts that don’t fit in the classic object-oriented mold. (There are a lot of th

Merging Interfaces

Merging Interfaces The simplest, and perhaps most common, type of declaration merging is interface merging. At the most basic level, the merge mechanically joins the members of both declarations into a single interface with the same name. interface Box { height: number; width: number; } interface Box { scale: number; } let box: Box = {height: 5, width: 6, scale: 10}; Non-function members of the interfaces must be unique. The compiler will issue an error if the interfaces both declare a