AgentSheet
Back
πŸ”·

TypeScript

languagetypesjavascript

Basic Types

TypeExample
stringlet x: string = "hi"
numberlet x: number = 42
booleanlet x: boolean = true
arraylet x: number[] or Array<number>
tuplelet x: [string, number] = ["a", 1]
enumenum Color { Red, Green }
anyBypasses type checking
unknownSafer than any, must narrow before use
neverNo value; for exhaustive checks
voidAbsence of return value
// readonly tuple
type Pair = readonly [string, number];

// const enum (inlined at compile time)
const enum Dir { Up, Down }

Interfaces vs Types

InterfaceType
Extendsextends& (intersection)
Declaration mergingβœ… Yes❌ No
Computed keysLimitedFull 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

TypeEffect
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"