TypeScript Cheat Sheet

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 4

TypeScript

Type
Full name is “type alias” and are used Supports more rich type-system These features are great for building libraries, describing existing
Key points
Cheat Sheet to provide names to type literals features than interfaces. JavaScript code and you may find you rarely reach for them in
mostly TypeScript applications.

Object Literal Syntax


Type vs Interface
Mapped Types
^ Interfaces can only describe
object shapel Acts like a map statement for the type system, allowing
^ Interfaces can be extended by type JSONResponse = {
an input type to change the structure of the new type.
declaring it mutliple timesi
^ In performance critical types
version: number;
// Field
type Artist = { name: string, bio: string }

interface comparison checks /** In bytes */


// Attached docs
Loop through each field
payloadSize: number;
//
in the type generic Sets type as a function with
can be faster.
type Subscriber<Type> = {
original type as param
outOfStock?: boolean;
// Optional
parameter “Type”
[Property in keyof Type]:

Think of Types Like Variables


update: (retryTimes: number) => void;
// Arrow func field
(newValue: Type[Property]) => void

Much like how you can create update(retryTimes: number): void;


// Function
}

variables with the same name in (): JSONResponse


// Type is callable
type ArtistSub = Subscriber<Artist>

different scopes, a type has


[key: string]: number;
// Accepts any index
// { name: (nv: string) => void,

similar semantics.
new (s: string): JSONResponse;
// Newable
// bio: (nv: string) => void }
Build with Utility Types readonly body: string;
// Readonly property
} Conditional Types
TypeScript includes a lot of
global types which will help you Terser for saving space, see Interface Cheat Sheet for
do common tasks in the type more info, everything but ‘static’ matches. Acts as “if statements” inside the type system. Created
system. Check the site for them. via generics, and then commonly used to reduce the
number of options in a type union.

Primitive Type Union Type Type from Value type HasFourLegs<Animal> =

Animal extends { legs: 4 } ? Animal

Useful for documentation mainly Describes a type which is one of many options, Re-use the type from an existing JavaScript : never

for example a list of known strings. runtime value via the typeof operator.
type SanitizedInput = string;

type MissingNo = 404; type Size =


const data = { ... }
type Animals = Bird | Dog | Ant | Wolf;

"small" | "medium" | "large" type Data = typeof data type FourLegs = HasFourLegs<Animals>

Object Literal Type // Dog | Wolf

Intersection Types Type from Func Return


type Location = {
Template Union Types
x: number;
A way to merge/extend types Re-use the return value from a
function as a type.
y: number;
type Location =
A template string can be used to combine and

}; { x: number } & { y: number }

const createFixtures = () => { ... }


manipulate text inside the type system.

// { x: number, y: number }
type Fixtures =
type SupportedLangs = "en" | "pt" | "zh";

ReturnType<typeof createFixtures>

type FooterLocaleIDs = "header" | "footer";

Tuple Type
Type Indexing

A tuple is a special-cased array with known


function test(fixture: Fixtures) {} type AllLocaleIDs =

types at specific indexes.


A way to extract and name from
`${SupportedLangs}_${FooterLocaleIDs}_id`;

type Data = [
a subset of a type. Type from Module // "en_header_id" | "en_footer_id"

location: Location,
type Response = { data: { ... } }

| "pt_header_id" | "pt_footer_id"

const data: import("./data").data


timestamp: string
| "zh_header_id" | "zh_footer_id"

]; type Data = Response["data"]

// { ... }
TypeScript

Overloads
Cheat Sheet
Common Syntax Optionally take properties from

existing interface or type

A callable interface can have multiple definitions

for different sets of parameters

Interface interface JSONResponse extends Response, HTTPAble {

version: number;

interface Expect {

JSDoc comment attached to show in editors


h
(matc er: boolean): strin g

Key points (matcher: string): boolean;

/** In bytes */

}
Used to describe the shape of payloadSize: number;

This property might not be on the object


objects, and can be extended by
others.

Get & Set


outOfStock?: boolean;

These are two ways to describe a

property which is a function


Almost everything in JavaScript is
an object and interface is built update: (retryTimes: number) => void;

Objects can have custom getters or setters


to match their runtime behavior. update(retryTimes: number): void;

interface Ruler {

You can call this object via () - ( functions get size(): numbe r

(): JSONResponse

in JS are objects which can be called )


set size(value: number | string);

Built-in Type Primitives }

new(s: string): JSONResponse;

You can use new on the object

this interface describes


boolean, string, number,
undefined, null, any, Usage
[key: string]: number;

unknown, never, void, Any property not described already is assumed

bigint, symbol to exist, and all properties must be numbers const r: Ruler = ...

readonly body: string;


.
r size = 12

Common Built-in JS Objects } r.size = "36"

Tells TypeScript that a property

can not be changed


Date, Error, Array, Map,
Set, Regexp, Promise

Type Literals Extension via merging


Object:
Generics Type parameter
Interfaces are merged, so multiple declarations will
{ field: string }
 add ne w fields to the type definition.
Declare a type which can change in your interface
Function:

interface API all {


C
(arg: number) => string
C
interface API all<Response> {
data: Response

Arrays:

data: Response

string[] or Array<string>

}
Tuple:
U sed here
C
interface API all {

[string, number] Usage


error?: Error

C
const api: API all<Artwork all> = C ...
}

Avoid
api data . // Artwork
Sets a constraint on the type

Object, String, Number, Boolean which means only types with a

You can constrain what types are accepted into the generic ‘ ’
status property can be used
Class conformance
parameter via the extends keyword.

C
interface API all<Response extends { status: number }> {
You can ensure a class conforms to an interface via implements:
data: Response

interface Syncable { sync(): void }

}
class Account implements Syncable { ... }
C
const api: API all<Artwork all> = C ...

.
api data status.
TypeScript

Class
A TypeScript class has a few type-specific extensions to ES2015 JavaScript These features are TypeScript specific language extensions which may
Key points
Cheat Sheet classes, and one or two runtime additions. never make it to JavaScript with the current syntax.

Creating an class instance Ensures that the class


Parameter Properties
Common Syntax Subclasses this class conforms to a set of
class ABC { ... }
interfaces or types A TypeScript specific extension to classes which
const abc = new ABC() automatically set an instance field to the input parameter.
class User extends Account implements Updatable, Serializable {

id: string;
// A field
class Location {

Parameters to the new ABC come


constructor(public x: number, public u
from the constructor function. displayName?: boolean;
// An optional field
y: n mber) {}

name!: string;
// A ‘trust me, it’s there’ field
}

private x vs #private
#attributes: Map<any, any>;
// A private field
const loc = new Location(20, 40);

The prefix private is a type-only


roles = ["user"];
// A field with a default
loc.x // 20

addition, and has no effect at loc.y // 40


readonly createdAt = new Date()

// A readonly field with a default


runtime. Code outside of the class
can reach into the item in the
following case:
u
constr ctor(i : stringd , email: string) {
The code called on ‘new’
class Bag {
u
s per(i )d ;
Abstract Classes
private item: any
this.email = email ;
In strict: true this code is checked against
} ...
the fields to ensure it is set up correctly A class can be declared as not implementable, but as existing to
be subclassed in the type system. As can members of the class.
};

Vs #private which is runtime abstract class Animal {

private and has enforcement


N h W ays to describe class N
abstract get ame(): string ;

inside the JavaScript engine that it set ame(name: string) { t is.name = name }

methods (and arrow N


print ame() {

is only accessible inside the class: verifyName = (name: string) = > { ... }

function fields)
"
console.log( Hello , " + h
t is.get ame())N ;

class Bag { #item: any }


A function with 2
}

sync(): Promise<{ ... }>

overload definitions }
sync(cb: ((result: string) => void)): void

‘this’ in classes

The value of ‘this’ inside a function sync(cb?: ((result: string) => void)): void | Promise<{ ... }> { ... }

class Dog extends N


Animal { get ame(): { ... } }
depends on how the function is
called. It is not guaranteed to
always be the class instance which u ID() { }

get acco nt Getters and setters


you may be used to in other
languages.

set accountID(value: string) { }

Decorators and Attributes


k R quest() { ... ri ate access is just to this class, protected
P v
You can use decorators on classes, class methods, accessors, property and
You can use ‘this parameters’, use private ma e e }

allows to subclasses. Only used for type


protected handleRequest() { }

parameters to methods.
the bind function, or arrow ... checking, public is the default.
functions to work around the issue import {

when it occurs.
u u 0;
Syncable, triggersSync, f
pre erCac e h , re quired

static # serCo nt =
Static fields / methods
static registerUser(user: User) { ... }

} from "mylib"

Type and Value

Surprise, a class can be used as


both a type or a value. h
static { t is.# serCo nt =u u -1 }

Static blocks for setting up static @Syncable

vars. ‘this’ refers to the static class


class User {

}
const a:Bag = new Bag()
@triggers Sync()

Type Value x<Type> {


Class type parameter save() { ... }

Generics class Bo

contents: Type

So, be careful to not do this: Declare a type which can constructor(value: Type) {

@pre ferCache(false)

class C implements Bag {}


change in your class
this.contents = value;

get displayName() { ... }

methods.
}

Used here
}

update(@required f
in o: Partial<User>) { ... }

const stringBo x x "


= new Bo ( a pac age ) k " }
TypeScript

Cheat Sheet
If Statements Expressions

Narrowing also occurs on the same line as code, when


Most narrowing comes from expressions inside if statements,
doing boolean operations
where different type operators narrow inside the new scope

Control
const input = getUserInput()

typeof (for primitives) “property” in object (for objects) input // string | number

Flow
const input = getUserInput()

input // string | number

const input = getUserInput()

input // string | { error : ... }

const inputLengt h =

(typeof input === "string" && input.lengt ) h || input

:
Analysis
// input string
if (typeof input === “string”) {
if (“error” in input) {

input // string
input // { error : ... }

} }

Key points instanceof (for classes) -


type guard functions (for anything)
const input = getUserInput()
const input = getUserInput()

CFA nearly always takes a union


input // number | number[]

input // number | number[]

and reduces the number of


types inside the union based on
if (input instanceof Array) {
if (Array.isArray(input)) {

logic in your code.


input // number[]
input // number[]

} }
Most of the time CFA works
inside natural JavaScript
boolean logic, but there are
ways to define your own Discriminated Unions Usage Assignment
functions which affect how
TypeScript narrows types. type Responses =
R
const response = get esponse()
Narrowing types using ‘as const’
| { status: 200, data: any }
response // Responses

| { status: 301, to: string }


j
Subfields in ob ects are treated as though they can
be mutated, and during assignment the type will be
| { status: 400, error: Error } w h
s itc (response.status) {

‘widened’ -
to a non literal version. The prefix ‘as
case 200: return response. at d a
const’ locks all types to their literal versions.
case 301: d
return re irect(response.to)

All members of the union have the same


case 400: return response.erro r
const data1 = {
typeof data1 = {

property name, CFA can discriminate on that.


name: agreus
"Z "
name: string

} }

A function with a return type describing the CFA const data2 = {


typeof data2 = {

Type Guards change for a new scope when it is true.


Usage
name: agreus
"Z "
name: agreus
"Z "

const response = get esponse()


R } as const }
E R
function is rror esponse(ob j: Response): ob j E R
is API rror esponse {
response // Response E
| API rror esponsR e

return obj instanceof AP IErrorRespons e

} E R
if (is rror esponse(response)) {

Tracks through related variables

Return type position describes


E
response // API rror esponse
R const response = get esponse()
R
what the assertion is
}
S
const is uccess esponse R

= res instanceof SuccessRespons e


A function describing CFA changes affecting the current Usage


S R
if (is uccess esponse)

Assertion Functions scope, because it throws instead of returning false. res.data // SuccessResponse

R
const res = get esponse() :

SuccessResponse ErrorResponse

Re -assignment updates types


R
function assert esponse(ob j: any) : asserts ob j is SuccessResponse {
res // |

! j instanceof SuccessResponse))
if ( (ob {

data: ..
throw new Error(“Not a success!”)
R
assert esponse(res )

let string | number = .

data r

Assertion functions change


// string | numbe
}
the current scope or throw
data
res // SuccessResponse

= "Hello"

}
data // string

You might also like