Typescript Cookbook
This blog talks about some tips and techniques while writing typescript code.
Function Declarations:
Example 1: Arguments with type:
function greet(person: string, date: Date) {console.log(`Hello ${person}, today is ${date.toDateString()}!`);}
Example 2: Return type:
function randomNumber(): number {return 26;}
// says that randomNumber will return a number
Example 3: Argument with an Object type:
function printCoord(pt: { x: number; y: number }) {console.log("The coordinate's x value is " + pt.x + pt.y);}
/* says that pt is an argument with type object having properties x and y */
Example 4: Argument with an Object type with Refactor:
type Point = {x: number;y: number;};// Exactly the same as the earlier examplefunction printCoord(pt: Point) {console.log("The coordinate's x value is " + pt.x + pt.y);}
/* says that pt is an argument with type Point
Example 5: Argument can be a string or number or something else
function printId(id: number | string) {if (typeof id === "string") {// In this branch, id is of type 'string'console.log(id.toUpperCase());} else {// Here, id is of type 'number'console.log(id);}}
Example 6: Argument that can have some set of values only
function printText(s: string, alignment: "left" | "right" | "center") {}printText("Hello, world", "left");interface Options {width: number;}function configure(x: Options | "auto") {// ...}configure({ width: 100 });configure("auto");
Example 7: Generic Function Declaration
function identity<Type>(arg: Type): Type {return arg;}identify(4);
identify("hello");
Interfaces:
Example 1: Only attributes:
interface IPerson {
name: string;
age: number;
}
Example 2: Attributes and Functions:
interface IEmployee {
empCode: number;
empName: string;
getSalary: (number) => number;
// arrow function that returns a number
getManagerName(number): string;
// function that returns a string and takes number as argument.}
Example 3: Generic Interface with Attributes and Functions:
interface IArray<Type> {length: number;pop(): Type | undefined; // function can either return an element of // data type Type or undefinedpush(...items: Type[]): number;
// function that returns a number may be the current index value.}
Example 4: Optional properties in Interfaces
interface IRectangle {length: number;breadth: number;area?: number;}
Example 5: Inheriting and Extending Interfaces
interface IHuman {type: string;origin: string;country?: string;}interface IMan extends IHuman {address: string;}
Handling Types which typescript can’t infer
Sometimes you will have information about the type of a value that TypeScript can’t know about.
For example, if you’re using document.getElementById
, TypeScript only knows that this will return some kind of HTMLElement
, but you might know that your page will always have an HTMLCanvasElement
with a given ID.
In this situation, you can use a type assertion to specify a more specific type:
const myCanvas = document.getElementById("main_canvas") as HTMLCanvasElement;
Like a type annotation, type assertions are removed by the compiler and won’t affect the runtime behavior of your code.
Note: You can also use the angle-bracket syntax (except if the code is in a .tsx
file), which is equivalent:
const myCanvas = <HTMLCanvasElement>document.getElementById("main_canvas");
Enums
Example 1:Numeric enums:
enum Direction {Up = 1,Down,Left,Right,}
Above, we have a numeric enum where Up
is initialized with 1
. All of the following members are auto-incremented from that point on. In other words, Direction.Up
has the value 1
, Down
has 2
, Left
has 3
, and Right
has 4
.
If we wanted, we could leave off the initializers entirely:
enum Direction {Up,Down,Left,Right,}
Here, Up
would have the value 0
, Down
would have 1
, etc.
Example 2:String enums
String enums are a similar concept, but have some subtle runtime differences as documented below. In a string enum, each member has to be constant-initialized with a string literal, or with another string enum member.
enum Direction {Up = "UP",Down = "DOWN",Left = "LEFT",Right = "RIGHT",}
While string enums don’t have auto-incrementing behavior.
Modules , Import, Exports
// @filename: maths.tsexport var pi = 3.14;export let squareTwo = 1.41;export const phi = 1.61;export class RandomNumberGenerator {}export function absolute(num: number) {if (num < 0) return num * -1;return num;}
These can be used in another file via the import
syntax:
import { pi, phi, absolute } from "./maths.js";console.log(pi);const absPhi = absolute(phi);
An import can be renamed using a format like import {old as new}
:
import { pi as π } from "./maths.js";console.log(π);