Basic Types
| Type | Example |
|---|
string | let x: string = "hi" |
number | let x: number = 42 |
boolean | let x: boolean = true |
array | let x: number[] or Array<number> |
tuple | let x: [string, number] = ["a", 1] |
enum | enum Color { Red, Green } |
any | Bypasses type checking |
unknown | Safer than any, must narrow before use |
never | No value; for exhaustive checks |
void | Absence of return value |
// readonly tuple
type Pair = readonly [string, number];
// const enum (inlined at compile time)
const enum Dir { Up, Down }
Interfaces vs Types
| Interface | Type |
|---|
| Extends | extends | & (intersection) |
| Declaration merging | β
Yes | β No |
| Computed keys | Limited | Full support |
| Mapped types | β No | β
Yes |
// Interface
interface User { name: string }
interface Admin extends User { role: string }
// Type
type User = { name: string }
type Admin = User & { role: string }
Generics
function identity<T>(x: T): T { return x }
// Constraints
function getProp<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key]
}
// Default
interface Box<T = string> { value: T }
Utility Types
| Type | Effect |
|---|
Partial<T> | All properties optional |
Required<T> | All properties required |
Readonly<T> | All properties readonly |
Pick<T, K> | Pick keys K from T |
Omit<T, K> | Omit keys K from T |
Record<K, V> | Object with keys K and values V |
Exclude<T, U> | T minus U (union) |
Extract<T, U> | T intersect U |
NonNullable<T> | Remove null/undefined |
ReturnType<F> | Return type of function F |
Parameters<F> | Parameters tuple of F |
Awaited<T> | Unwrap Promise |
type User = { id: number; name: string }
type PartialUser = Partial<User> // { id?: number; name?: string }
type NameOnly = Pick<User, 'name'> // { name: string }
type NoName = Omit<User, 'name'> // { id: number }
type IdMap = Record<string, User> // { [k: string]: User }
Type Guards & Narrowing
// typeof
if (typeof x === "string") { /* x is string */ }
// instanceof
if (x instanceof Date) { /* x is Date */ }
// in
if ("name" in obj) { /* obj has name */ }
// Custom type guard
function isFish(pet: Fish | Bird): pet is Fish {
return (pet as Fish).swim !== undefined
}
Conditional Types
type IsString<T> = T extends string ? true : false
type A = IsString<"hi"> // true
type B = IsString<123> // false
// Infer
type Unwrap<T> = T extends Promise<infer U> ? U : T
type X = Unwrap<Promise<number>> // number
Mapped Types
type Readonly<T> = { readonly [K in keyof T]: T[K] }
type Optional<T> = { [K in keyof T]?: T[K] }
// Key remapping (4.1+)
type Getters<T> = { [K in keyof T as `get${Capitalize<string & K>}`]: () => T[K] }
Template Literal Types
type EventName = "click" | "scroll"
type Handler = `on${Capitalize<EventName>}` // "onClick" | "onScroll"
type Concat<A extends string, B extends string> = `${A}${B}`
type X = Concat<"hello", " world"> // "hello world"
Declaration Merging
// Interfaces merge
interface Window { myProp: number }
interface Window { otherProp: string }
// Window has both myProp and otherProp
// Module augmentation
declare module "my-module" {
export function extra(): void
}
Module Patterns
// Export
export type { User }
export type { User as U }
export type * from "./types"
// Import
import type { User } from "./types"
import type { User as U } from "./types"