Executive Summary
TypeScript in 2026 is used in 74% of GitHub repositories with JavaScript in their stack, 78% of npm packages ship with TypeScript declarations, and 70% of JavaScript developer job listings require or prefer TypeScript. The language has evolved from a simple type annotation layer to a powerful type-level programming language capable of computing types from strings, transforming object shapes, and enforcing end-to-end type safety across client-server boundaries.
This guide covers every TypeScript feature from basic type annotations to advanced type-level programming. It documents 21 built-in utility types, 35 compiler options, 20 version releases with their key features, TS vs JS comparison across 14 dimensions, and TypeScript support across 12 frameworks. Whether you are starting with TypeScript or pushing the limits of conditional types and template literal types, this is the definitive reference.
- 74% of JS repos now use TypeScript, up from 8% in 2017. TypeScript is the default for new projects in Next.js, Angular, SvelteKit, and Astro.
- Node.js 22+ runs TypeScript natively with --experimental-strip-types, eliminating the build step for simple scripts. TS 5.8 added erasableSyntaxOnly to ensure compatibility.
- satisfies (TS 4.9) changed how developers write constants, providing type validation without widening. Combined with as const, it gives both safety and precision.
- End-to-end type safety is the norm: tRPC, Prisma, Drizzle, and Hono enable type-safe APIs from database schema to client components without manual type synchronization.
74%
GitHub repos using TS
78%
npm packages with types
6.0
Latest TS version
21
Built-in utility types
Part 1: Basic Types
TypeScript adds static types to JavaScript. Primitive types: string, number, boolean, null, undefined, symbol, bigint. Special types: any (disables checking), unknown (safe any, requires narrowing), never (impossible values), void (no return value). Object types: object (non-primitive), Record (key-value), arrays (number[] or Array<number>), tuples ([string, number]), and functions ((x: string) => void).
Type annotations: let name: string = "Alice". Type inference: let name = "Alice" (inferred as string). Function parameters always need annotations: function greet(name: string): string. Return types can be inferred but explicit annotations catch bugs. Union types: string | number (either type). Literal types: "success" | "error" (specific values). Intersection types: A & B (both types combined). Nullable types: string | null (with strictNullChecks).
Type narrowing: TypeScript tracks types through control flow. After if (typeof x === "string"), x is narrowed to string. After if (x !== null), null is removed. The in operator narrows: if ("name" in x). instanceof narrows: if (x instanceof Date). Discriminated unions narrow with a shared literal property: switch (result.status). Custom type guards: function isUser(x: unknown): x is User.
TypeScript Adoption (2017-2026)
Source: OnlineTools4Free Research
Part 2: Interfaces vs Types
Both interface and type define object shapes. Interfaces: support declaration merging (extending across files/modules), extend with extends keyword, can be implemented by classes. Type aliases: support unions (string | number), intersections (A & B), mapped types, conditional types, template literal types, and tuple types. Interfaces are slightly faster for compilation due to caching.
Convention: use interface for public API contracts and object shapes that may be extended; use type for unions, intersections, utility type transformations, and complex types. In practice, most teams standardize on one or the other. Both are structurally typed: a value matching the shape is assignable regardless of which keyword defined the type. Module augmentation only works with interfaces (declaration merging).
TypeScript vs JavaScript Comparison
14 rows
| Feature | TypeScript | JavaScript | Benefit |
|---|---|---|---|
| Static Type System | Yes (compile-time type checking) | No (runtime errors only) | Catch type errors before running code, better IDE support |
| Interfaces & Type Aliases | Yes (interface, type keywords) | No | Define contracts, document shapes, enable IDE autocomplete |
| Generics | Yes (full generics with constraints) | No | Reusable type-safe functions, classes, and components |
| Enums | Yes (numeric and string enums) | No (use const objects or unions) | Named constants with reverse mapping (numeric) |
| Decorators | Yes (TC39 standard, TS 5.0+) | Stage 3 proposal | Metadata, dependency injection, validation, logging |
| Access Modifiers | public, private, protected, readonly | #private fields only (ES2022) | Encapsulation at the type level |
| Module Types | .d.ts declaration files | JSDoc comments (partial) | Type definitions for libraries without TS source |
| Path Aliases | paths in tsconfig.json | Requires bundler config | Clean imports (@/components vs ../../../components) |
| IDE Support | Full (autocomplete, refactoring, errors) | Partial (with JSDoc or tsconfig checkJs) | 10-25% fewer bugs, faster development |
| Build Step Required | Yes (tsc, esbuild, swc, or strip) | No (runs directly in browser/Node) | JS is simpler for scripts; TS catches errors earlier |
| File Extension | .ts, .tsx, .mts, .cts | .js, .jsx, .mjs, .cjs | TypeScript extensions signal typed files |
| Runtime Behavior | Types erased at compile time (zero runtime cost) | N/A | No performance overhead from types |
| Learning Curve | Higher (type system complexity) | Lower (no type annotations) | Investment pays off in medium-large codebases |
| Ecosystem | DefinitelyTyped (@types), native .d.ts | Universal (all npm packages) | 95%+ of popular npm packages have TS types |
Part 3: Generics
Generics make functions, classes, and interfaces work with multiple types while maintaining type safety. Basic syntax: function identity<T>(x: T): T. The type parameter T is inferred from the argument: identity("hello") infers T as string. Multiple parameters: function pair<A, B>(a: A, b: B): [A, B]. Constraints restrict T: <T extends { length: number }> ensures T has a length property. Default type: <T = string>.
Generic classes: class Container<T> { constructor(private value: T) {} get(): T { return this.value; } }. Generic interfaces: interface Repository<T> { find(id: string): T | null; save(entity: T): void; }. Generic React components: function List<T>(props: { items: T[]; render: (item: T) => ReactNode }) {}. Const type parameters (TS 5.0): <const T>(x: T) infers T as a literal type instead of widening, similar to as const but at the call site.
Part 4: Utility Types Reference
TypeScript provides 21 built-in utility types for common type transformations. Partial, Required, Readonly transform property modifiers. Pick, Omit select/exclude properties. Record creates key-value types. Exclude, Extract filter union members. NonNullable removes null/undefined. ReturnType, Parameters, ConstructorParameters, InstanceType extract function/class types. Awaited unwraps promises. Template literal types Uppercase, Lowercase, Capitalize, Uncapitalize transform strings. NoInfer (TS 5.4) controls inference sites.
Built-in Utility Types Reference (21 Types)
21 rows
| Utility Type | Description | Example | Use Case |
|---|---|---|---|
| Partial<T> | Makes all properties of T optional. Equivalent to { [P in keyof T]?: T[P] }. | Partial<User> // { name?: string; age?: number } | Update functions where only some fields are provided (patch/merge operations) |
| Required<T> | Makes all properties of T required. Opposite of Partial. Equivalent to { [P in keyof T]-?: T[P] }. | Required<Partial<User>> // { name: string; age: number } | Ensuring all optional config has been resolved with defaults |
| Readonly<T> | Makes all properties of T readonly. Prevents reassignment at the type level. | Readonly<User> // { readonly name: string; readonly age: number } | Immutable state objects, frozen configs |
| Record<K, V> | Constructs a type with keys K and values V. Creates a mapped type from union to value type. | Record<"a" | "b", number> // { a: number; b: number } | Dictionaries, lookup tables, index signatures with known keys |
| Pick<T, K> | Picks a subset of properties K from type T. Creates a new type with only the specified keys. | Pick<User, "name" | "email"> // { name: string; email: string } | API response shapes, component props subsets |
| Omit<T, K> | Removes properties K from type T. Complement of Pick. | Omit<User, "password"> // { name: string; email: string } | Excluding sensitive fields, creating public DTOs from internal models |
| Exclude<T, U> | Removes union members from T that are assignable to U. Works on union types. | Exclude<"a" | "b" | "c", "a"> // "b" | "c" | Filtering union types, removing specific enum values |
| Extract<T, U> | Extracts union members from T that are assignable to U. Opposite of Exclude. | Extract<string | number | boolean, string> // string | Selecting specific types from a union |
| NonNullable<T> | Removes null and undefined from T. Equivalent to Exclude<T, null | undefined>. | NonNullable<string | null | undefined> // string | Asserting non-null values after null checks |
| ReturnType<T> | Extracts the return type of a function type T. Uses conditional types internally. | ReturnType<typeof fetchUser> // Promise<User> | Inferring return types without manually duplicating them |
| Parameters<T> | Extracts parameter types of a function as a tuple. Uses conditional types with infer. | Parameters<typeof fn> // [string, number] | Wrapping functions, creating higher-order function signatures |
| ConstructorParameters<T> | Extracts constructor parameter types of a class. | ConstructorParameters<typeof Date> // [value: string | number] | Factory functions that mirror constructor signatures |
| InstanceType<T> | Extracts the instance type from a constructor type T. | InstanceType<typeof Date> // Date | Working with class references dynamically |
| ThisParameterType<T> | Extracts the this parameter type from a function type. | ThisParameterType<typeof fn> // MyClass | Extracting this context for method binding |
| OmitThisParameter<T> | Removes the this parameter from a function type. | OmitThisParameter<typeof fn> // (x: string) => void | Creating unbound function types |
| Awaited<T> | Recursively unwraps Promise types. Awaited<Promise<Promise<string>>> becomes string. | Awaited<Promise<string>> // string | Getting the resolved type of async functions |
| Uppercase<S> | Converts string literal type to uppercase. Template literal type helper. | Uppercase<"hello"> // "HELLO" | Enforcing naming conventions in types |
| Lowercase<S> | Converts string literal type to lowercase. | Lowercase<"HELLO"> // "hello" | Normalizing string literal types |
| Capitalize<S> | Capitalizes first character of string literal type. | Capitalize<"hello"> // "Hello" | Generating getter/setter method name types |
| Uncapitalize<S> | Lowercases first character of string literal type. | Uncapitalize<"Hello"> // "hello" | Reverse of Capitalize for property names |
Page 1 of 2
Part 5: Conditional Types
Conditional types select between two types based on a condition: T extends U ? X : Y. If T is assignable to U, the type resolves to X, otherwise Y. The infer keyword extracts types within conditions: type ElementOf<T> = T extends Array<infer U> ? U : never. Conditional types distribute over unions: (string | number) extends string ? true : false becomes false | false = false. To prevent distribution, wrap in tuple: [T] extends [U] ? X : Y.
Advanced patterns: recursive conditional types (TS 4.5+) for deep transformations: type DeepReadonly<T> = T extends object ? { readonly [K in keyof T]: DeepReadonly<T[K]> } : T. The infer keyword in template literal types: type ParseRoute<T> = T extends `/${infer Segment}/${infer Rest}` ? [Segment, ...ParseRoute<Rest>] : [T]. Conditional types power all built-in utility types and enable type-level string parsing, path resolution, and SQL query typing.
Part 6: Mapped Types
Mapped types iterate over keys of a type to create a new type. Basic syntax: { [P in keyof T]: NewType }. Modifier addition (+): { [P in keyof T]+?: T[P] } makes all optional. Modifier removal (-): { [P in keyof T]-?: T[P] } makes all required. Built-in mapped types: Partial (+?), Required (-?), Readonly (+readonly).
Key remapping (TS 4.1): { [P in keyof T as NewKey]: T[P] }. Filter keys: { [P in keyof T as T[P] extends string ? P : never]: T[P] } keeps only string-valued properties. Rename keys: { [P in keyof T as `get${Capitalize<string & P>}`]: () => T[P] } generates getter methods. Mapped types combined with conditional types and template literal types form the backbone of type-level programming in TypeScript.
Part 7: Template Literal Types
Template literal types (TS 4.1) use backtick syntax at the type level to create new string types. Basic: type Greeting = `Hello, ${string}`. With unions: type Method = "GET" | "POST"; type Endpoint = `${Method} /api/${string}` produces "GET /api/..." | "POST /api/...". Intrinsic types: Uppercase<"hello"> = "HELLO", Capitalize<"hello"> = "Hello".
Pattern matching with infer: type ExtractParam<T> = T extends `${string}:${infer P}` ? P : never. Use cases: type-safe event names (`on${Capitalize<EventName>}`), CSS property types, routing (`/users/${string}/posts/${number}`), API paths, object dot-notation paths, and i18n translation keys. Combined with mapped types, template literal types enable generating method names, event handlers, and getters/setters from property names.
Part 8: Decorators
TypeScript 5.0 implemented TC39 stage 3 decorators, different from the older experimentalDecorators. Standard decorators receive (target, context) where context includes name, kind (class, method, field, getter, setter, accessor), access (get/set), static, private, addInitializer. Class decorators can modify or replace the class. Method decorators can wrap the original method. Field decorators can provide initializers.
Decorator metadata (TS 5.2): Symbol.metadata on the class provides a shared metadata object that decorators populate and consumers read. Use cases: dependency injection (Angular, NestJS), validation (@IsEmail, @MinLength), ORM column definitions (@Column, @PrimaryKey), route definitions (@Get, @Post), serialization, logging, and caching. Libraries: Angular (required), NestJS (required), TypeORM (required), class-validator, class-transformer.
Part 9: Enums
Numeric enums auto-increment from 0: enum Direction { Up, Down, Left, Right }. String enums require explicit values: enum Color { Red = "RED", Blue = "BLUE" }. const enums are inlined at compile time (no runtime object). Regular enums emit a JavaScript object with reverse mapping (for numeric enums).
Modern alternative: const objects with as const. const Direction = { Up: "UP", Down: "DOWN" } as const; type Direction = (typeof Direction)[keyof typeof Direction]; // "UP" | "DOWN". Advantages: tree-shakeable, no runtime overhead, compatible with isolatedModules and erasableSyntaxOnly (Node.js type stripping). The trend in the TypeScript community is moving away from enums toward const objects for most use cases.
Part 10: Modules and Declaration Files
TypeScript supports ES modules (import/export) and CommonJS (require/module.exports). Module resolution strategies: Node10 (legacy), NodeNext (modern Node.js with package.json exports), Bundler (Vite/webpack). Use verbatimModuleSyntax to enforce explicit import type for type-only imports. Declaration files (.d.ts) provide type information for JavaScript libraries. Generated with declaration: true or written manually.
DefinitelyTyped (@types/package) provides community-maintained types for packages without built-in types. Module augmentation extends existing types: declare module "express" { interface Request { user?: User } }. Global augmentation: declare global { interface Window { myGlobal: string } }. Ambient declarations: declare module "untyped-lib" for untyped packages.
TypeScript Version Timeline (1.0 - 6.0)
20 rows
| Version | Release | Key Features | Significance |
|---|---|---|---|
| 1.0 | April 2014 | Initial release, basic type annotations, interfaces, classes, modules | TypeScript publicly launched |
| 1.5 | July 2015 | Destructuring, spread, for..of, symbols, computed properties, template strings, modules (ES6) | ES6 alignment |
| 2.0 | September 2016 | Strict null checks (--strictNullChecks), control flow type analysis, tagged unions, readonly, never type | Null safety introduced |
| 2.1 | December 2016 | keyof, lookup types, mapped types (Partial, Readonly, Record, Pick) | Type-level programming begins |
| 2.8 | March 2018 | Conditional types (T extends U ? X : Y), infer keyword | Advanced type-level computation |
| 3.0 | July 2018 | Project references, tuples in rest/spread, unknown type | Monorepo support |
| 4.0 | August 2020 | Variadic tuple types, labeled tuple elements, class property inference from constructors | Advanced tuple types |
| 4.1 | November 2020 | Template literal types, key remapping in mapped types, recursive conditional types | String-level type computation |
| 4.5 | November 2021 | Awaited type, tail-call optimization for conditional types, type-only import specifiers | Performance and async types |
| 4.9 | November 2022 | satisfies operator, auto-accessors, unlisted property narrowing with in | satisfies revolutionizes type narrowing |
| 5.0 | March 2023 | Decorators (TC39 stage 3), const type parameters, enum improvements, --moduleResolution bundler | Standard decorators, bundler mode |
| 5.2 | August 2023 | using and await using (Explicit Resource Management), decorator metadata | Resource management |
| 5.3 | November 2023 | Import attributes, resolution-mode in import types, switch(true) narrowing | Import assertions evolution |
| 5.4 | March 2024 | NoInfer utility type, preserved narrowing in closures, Object.groupBy/Map.groupBy | Closure narrowing fix |
| 5.5 | June 2024 | Inferred type predicates, control flow narrowing for indexed accesses, regex syntax checking | Inferred type guards |
| 5.6 | September 2024 | Disallowed nullish coalescing on non-nullable, iterator helpers types, region-prioritized diagnostics | Stricter safety defaults |
| 5.7 | December 2024 | Isolated declarations, path rewriting for declaration emit, node22 module target | Parallel declaration emit |
| 5.8 | March 2025 | Branded types improvements, module body checking, --erasableSyntaxOnly | Node.js native TS stripping |
| 5.9 | Q2 2025 | Inferred generic constraints, return type inference improvements | Better inference |
| 6.0 | Q3 2025 | Explicit resource management finalization, module expression types, performance overhaul | Major version milestone |
Part 11: Compiler Options (35+)
The tsconfig.json file configures the TypeScript compiler. Key sections: compilerOptions (type checking, module, emit, JSX), include/exclude (file globs), references (project references). The most important option is strict: true, which enables all strict type checking flags. For module resolution, match your runtime: NodeNext for Node.js, Bundler for Vite/webpack.
Compiler Options Reference (35+)
35 rows
| Option | Category | Default | Description |
|---|---|---|---|
| target | Emit | ES5 | ECMAScript version for emitted JavaScript. Determines which features are downleveled. |
| module | Module | CommonJS | Module system for emitted code. Use NodeNext for Node.js, Preserve for bundlers. |
| moduleResolution | Module | Node10 | How modules are resolved. Bundler mode aligns with Vite/webpack/esbuild behavior. |
| strict | Type Checking | false | Enables ALL strict checks. Equivalent to enabling strictNullChecks, strictFunctionTypes, etc. |
| strictNullChecks | Type Checking | false | null and undefined are distinct types, not assignable to other types without checking. |
| strictFunctionTypes | Type Checking | false | Function parameter types are checked contravariantly (safer type narrowing). |
| noImplicitAny | Type Checking | false | Error on expressions and declarations with an implied any type. |
| noImplicitReturns | Type Checking | false | Error when not all code paths in function return a value. |
| noUnusedLocals | Type Checking | false | Error on unused local variables. |
| noUnusedParameters | Type Checking | false | Error on unused function parameters. Prefix with _ to suppress. |
| noUncheckedIndexedAccess | Type Checking | false | Adds undefined to index signature results. arr[0] becomes T | undefined. |
| exactOptionalPropertyTypes | Type Checking | false | Distinguishes between optional (missing) and undefined (present but undefined) properties. |
| esModuleInterop | Module | false | Enables interop between CommonJS and ES modules. Allows default imports from CJS. |
| allowImportingTsExtensions | Module | false | Allows importing .ts/.tsx files directly. Requires noEmit or emitDeclarationOnly. |
| resolveJsonModule | Module | false | Allows importing .json files with type inference from the JSON structure. |
| isolatedModules | Module | false | Ensures each file can be independently transpiled. Required for esbuild/swc/Babel. |
| isolatedDeclarations | Module | false | Ensures .d.ts files can be generated without full type checking. Enables parallel declaration emit. TS 5.7+. |
| verbatimModuleSyntax | Module | false | Imports/exports not marked type-only are preserved. Replaces importsNotUsedAsValues. |
| outDir | Emit | Output directory for compiled files. | |
| rootDir | Emit | Root directory of input files. Determines output directory structure. |
Page 1 of 2
Part 12: Migrating from JavaScript
Step 1: Add tsconfig.json with allowJs: true, checkJs: false. This allows .ts and .js files to coexist. Step 2: Rename files from .js to .ts one at a time, starting with leaf modules (utilities, helpers) that have no dependencies. Step 3: Add type annotations incrementally: function parameters first, then return types, then interfaces for data shapes. Use any as an escape hatch for complex types that will be refined later.
Step 4: Enable strict checks gradually. Start with noImplicitAny (forces parameter annotations), then strictNullChecks (catches null/undefined errors), then full strict. Each flag will reveal a wave of errors to fix. Step 5: Add @types packages for third-party dependencies. Step 6: Remove allowJs when all files are .ts. Tools: ts-migrate (Airbnb) automates file renaming and adds placeholder types. Most medium codebases (50-200 files) can be migrated in 2-4 weeks.
Part 13: Framework TypeScript Support
Framework TypeScript Support (12 Frameworks)
12 rows
| Framework | First-Class TS | TS Support | Type Generation | Notes |
|---|---|---|---|---|
| Next.js | Yes (built-in) | Full (auto-generated tsconfig, typed API routes, typed middleware, App Router types) | Automatic route types, Link type safety | TypeScript is the default for new Next.js projects since v13 |
| React | Yes | Full (@types/react, generic components, hooks types, JSX.IntrinsicElements) | N/A | Most popular TS framework. React 19 ships its own types |
| Vue 3 | Yes (built-in) | Full (defineComponent, script setup, Volar, typed refs, typed emits) | Auto-generated component types in SFCs | Vue 3 rewritten in TypeScript, first-class support |
| Angular | Yes (required) | Full (decorators, dependency injection, typed forms, typed HTTP) | Angular CLI generates typed code | Angular was the first major framework to adopt TypeScript (v2, 2016) |
| Svelte | Yes (built-in) | Full (lang="ts" in script, typed stores, typed events) | Typed component props | SvelteKit has full TypeScript support |
| Astro | Yes (built-in) | Full (typed frontmatter, typed content collections, typed API routes) | Content collection types | Built with TypeScript, excellent type inference |
| Express.js | Via @types | Good (@types/express, typed Request/Response, typed middleware) | N/A | Community types, well-maintained |
| Fastify | Yes (built-in) | Full (typed routes, typed plugins, JSON Schema to TypeScript) | Type providers (json-schema-to-ts, typebox) | Best backend TS experience, type providers for schema validation |
| tRPC | Yes (TypeScript-first) | Full (end-to-end type safety, no code generation) | Automatic (inferred from server to client) | Entire API contract is TypeScript types, no REST/GraphQL needed |
| Prisma | Yes (TypeScript-first) | Full (generated types from schema, typed queries, typed relations) | Full type generation from prisma.schema | Schema-to-type generation, autocompletion for all queries |
| Drizzle ORM | Yes (TypeScript-first) | Full (schema as TS code, typed queries, type-safe SQL) | Schema IS the type definition (no generation step) | Type-safe SQL builder, schema defined in TypeScript |
| Hono | Yes (TypeScript-first) | Full (typed routes, typed middleware, typed validators) | RPC mode with end-to-end type safety | Fastest-growing backend framework, Web Standard APIs |
Glossary (50+ Terms)
Type Inference
Core ConceptTypeScript ability to automatically determine the type of a variable, parameter, or return value without explicit annotation. TypeScript infers from initialization (let x = 5 infers number), function return types, generic type arguments, and contextual typing (callback parameters). Best practice: rely on inference for local variables and return types; annotate function parameters and public API boundaries.
Type Narrowing
Core ConceptThe process of refining a type to a more specific type within a code block. Narrowing occurs through: typeof checks (typeof x === "string"), instanceof checks, equality checks (=== null), truthiness checks, in operator, custom type guards (x is Type), discriminated unions, and control flow analysis. After narrowing, TypeScript knows the more specific type and provides appropriate autocomplete and type safety.
Type Guard
Core ConceptA function that narrows the type of a variable. Built-in guards: typeof, instanceof, in. Custom type guards use the "is" keyword: function isUser(x: unknown): x is User { return typeof x === "object" && x !== null && "name" in x; }. TS 5.5+ can infer type predicates automatically from function bodies. Type guards enable safe narrowing of union types and unknown values.
Structural Typing
Type SystemTypeScript type system is structural (duck typing), not nominal. Two types are compatible if they have the same shape (properties), regardless of their names or where they were declared. { name: string } is assignable to interface User { name: string } even without explicit implements. This differs from Java/C# where types must explicitly declare relationships. Branded types add nominal-like behavior.
Discriminated Unions
PatternsA union type where each member has a literal type property (the discriminant) that TypeScript uses for narrowing. Example: type Result = { status: "success"; data: string } | { status: "error"; error: Error }. Switching on result.status narrows to the correct variant. The discriminant must be a literal type (string, number, boolean literal). Essential pattern for state machines, API responses, and event handling.
Conditional Types
Advanced TypesTypes that depend on a condition: T extends U ? X : Y. If T is assignable to U, the type is X; otherwise Y. Distribute over unions by default: (A | B) extends U ? X : Y becomes (A extends U ? X : Y) | (B extends U ? X : Y). The infer keyword extracts types within conditions: T extends Array<infer U> ? U : never extracts the element type. Foundation of many utility types (ReturnType, Parameters, Awaited).
Mapped Types
Advanced TypesTypes that transform properties of an existing type. Syntax: { [P in keyof T]: NewType }. Modifiers: +/- readonly, +/- ? (optional). Key remapping (TS 4.1): { [P in keyof T as NewKey]: T[P] }. Built-in mapped types: Partial, Required, Readonly, Record, Pick, Omit. Custom example: type Getters<T> = { [P in keyof T as `get${Capitalize<string & P>}`]: () => T[P] } generates getter methods from properties.
Template Literal Types
Advanced TypesTypes that use template string syntax to create new string literal types. Syntax: type Route = `/api/${string}`. Combined with unions: type Method = "GET" | "POST"; type Endpoint = `${Method} /api/${string}`. Intrinsic types Uppercase, Lowercase, Capitalize, Uncapitalize manipulate strings at the type level. Used for: type-safe routing, CSS-in-JS property names, event handler names, and key remapping in mapped types.
Generic Constraints
GenericsRestrictions on generic type parameters using the extends keyword. function getLength<T extends { length: number }>(x: T): number constrains T to types with a length property. Constraints ensure the generic type has the required shape. Multiple constraints use intersection: T extends Serializable & Comparable. Default type parameters: <T = string> provides a fallback when no type argument is given.
Declaration Files (.d.ts)
EcosystemFiles containing only type declarations (no runtime code). Used to describe the shape of JavaScript libraries for TypeScript consumers. Generated automatically with declaration: true in tsconfig. DefinitelyTyped (@types/package) provides community-maintained declarations for packages without built-in types. Ambient declarations (declare module "pkg") provide types for untyped modules. Declaration files are the bridge between JS and TS ecosystems.
Type Assertion
Core ConceptTells TypeScript to treat a value as a specific type. Syntax: value as Type or <Type>value (JSX conflicts). Does NOT perform runtime conversion. Use sparingly; prefer type guards for safety. The as const assertion makes literals readonly and literal-typed: const x = [1, 2] as const is readonly [1, 2], not number[]. The satisfies operator (TS 4.9) validates type compatibility while preserving the inferred type.
satisfies Operator
Core ConceptAdded in TS 4.9. Validates that a value matches a type without widening the inferred type. const config = { port: 3000, host: "localhost" } satisfies Config ensures config matches Config while preserving literal types (port is 3000, not number). Unlike as, satisfies does not lose type information. Unlike annotation (: Config), it does not widen types. Best of both worlds for configuration objects and constants.
never Type
Type SystemThe bottom type that represents values that never occur. Functions that throw errors or have infinite loops return never. In unions, never is absorbed: string | never = string. In intersections, never absorbs: string & never = never. Used in exhaustive switch checks: a default case that assigns to never will error if new union members are added. Conditional types use never to filter: Extract and Exclude rely on distributing to never.
unknown Type
Type SystemThe top type that represents any value but requires type checking before use. Safer alternative to any: you cannot access properties or call methods on unknown without narrowing first. Use unknown for API boundaries, parsed JSON, user input, and catch clause variables. Narrow with typeof, instanceof, type guards, or as. any disables type checking; unknown enforces it.
Branded Types
PatternsA pattern for creating nominal-like types in TypeScript structural type system. type UserId = string & { __brand: "UserId" }. A plain string is not assignable to UserId without a constructor function. Prevents mixing semantically different values that share the same primitive type (UserId vs ProductId, both strings). Libraries like zod and io-ts support branded types for validated values.
Enum
Core ConceptA set of named constants. Numeric enums auto-increment: enum Direction { Up, Down, Left, Right }. String enums require explicit values: enum Color { Red = "RED" }. const enums are inlined at compile time (no runtime object). Enums are one of the few TypeScript features that emit runtime code. Alternative: as const objects with satisfies for type-safe constants without runtime cost. TS 5.8+ erasableSyntaxOnly flag disallows enums for Node.js type stripping.
Decorator
Language FeatureA function that modifies a class, method, property, or parameter. TC39 standard decorators (TS 5.0+) differ from experimental decorators (experimentalDecorators). Standard syntax: @log class MyClass {}. Decorators receive a target and context object. Use cases: logging, validation, dependency injection, ORM column definitions, route definitions. Angular, NestJS, and TypeORM rely heavily on decorators.
Module Augmentation
EcosystemExtending existing module types by declaring the same module name. Used to add properties to third-party types: declare module "express" { interface Request { user?: User } }. Can augment interfaces (merging) but not type aliases. Global augmentation: declare global { interface Window { myGlobal: string } }. Module augmentation must be in a file with import/export to be treated as a module.
Type Predicate
Core ConceptA special return type annotation (paramName is Type) that tells TypeScript a function is a type guard. function isString(x: unknown): x is string { return typeof x === "string"; }. After calling isString(value), TypeScript narrows value to string in the truthy branch. TS 5.5 can infer type predicates automatically from function bodies, reducing boilerplate.
Variance
Type SystemHow type relationships change with generic type parameters. Covariant (out): if Dog extends Animal, then Array<Dog> extends Array<Animal> (read positions). Contravariant (in): if Dog extends Animal, then (animal: Animal) => void is NOT assignable to (dog: Dog) => void (write positions). TypeScript 4.7 added explicit variance annotations: interface Foo<out T> {} (covariant), interface Bar<in T> {} (contravariant). strictFunctionTypes enables correct contravariant checking for function parameters.
Intersection Types
Type SystemCombines multiple types into one using the & operator. type A = { name: string } & { age: number } has both name and age. With primitives: string & number = never (no value is both). Used for: mixin patterns, adding properties to existing types, combining interfaces. Differs from union (|): intersection requires ALL members, union requires ANY member.
Index Signatures
Type SystemDefine types for dynamic property names. Syntax: { [key: string]: number } allows any string key with a number value. Limits: all properties must match the index signature type. Use Record<string, number> as shorthand. For stricter typing, prefer mapped types or specific keys. noUncheckedIndexedAccess (TS 4.1) adds | undefined to index access results, making obj[key] return T | undefined instead of T.
Type vs Interface
Core ConceptBoth define object shapes, but differ in capabilities. Interfaces: support declaration merging (extending across files), extend other interfaces (extends), can be implemented by classes (implements). Type aliases: support unions (A | B), intersections (A & B), mapped types, conditional types, template literal types, and tuple types. Performance: interfaces are slightly faster in compilation. Convention: use interface for public APIs and object shapes; use type for unions, intersections, and utility types.
Tuple Types
Core ConceptFixed-length arrays where each element has a specific type. Syntax: [string, number] is a two-element array with string first, number second. Labeled tuples (TS 4.0): [name: string, age: number]. Optional elements: [string, number?]. Rest elements: [string, ...number[]]. Variadic tuple types (TS 4.0): [...T, ...U] for generic tuple manipulation. Used for: function parameter types, destructuring return values, and typed arrays.
Const Assertion
Core ConceptThe as const assertion makes values deeply readonly and narrows types to their literal values. const x = [1, 2, 3] as const becomes readonly [1, 2, 3] (not number[]). const obj = { a: 1 } as const becomes { readonly a: 1 } (not { a: number }). Essential for: enum-like objects, configuration constants, tuple definitions, and discriminated union values. Const type parameters (TS 5.0): <const T>(x: T) infers T as a literal type.
Explicit Resource Management
Language FeatureTypeScript 5.2 added using and await using declarations for deterministic cleanup of resources (file handles, database connections, locks). Objects implementing Symbol.dispose or Symbol.asyncDispose are automatically cleaned up when the scope exits. Syntax: using file = openFile("path"); // file[Symbol.dispose]() called at scope end. Replaces try/finally patterns. ECMAScript TC39 proposal (stage 3).
Project References
BuildA mechanism for structuring TypeScript codebases into multiple smaller projects that reference each other. Defined in tsconfig.json with references and composite options. Benefits: faster incremental builds (only rebuild changed projects), enforce module boundaries, independent compilation. Essential for monorepos. Build with tsc --build (or tsc -b). Each project produces .d.ts and .tsbuildinfo files.
Type-Level Programming
Advanced TypesUsing TypeScript type system as a computation language. Conditional types act as if/else. Mapped types act as loops. Template literal types act as string operations. Recursive types enable iteration. Infer extracts types. The result: types that compute other types. Examples: parsing routes from strings, building SQL query type checkers, inferring API response types from schema. Trade-off: complex types slow compilation and are hard to debug.
Ambient Declaration
EcosystemType declarations for code that exists outside of TypeScript (JavaScript libraries, global variables, environment). Syntax: declare function alert(message: string): void; declare module "untyped-lib" { export function foo(): void; }. Ambient declarations do not generate code; they only inform the type checker. Placed in .d.ts files or declare blocks. Global augmentation: declare global { } adds to the global scope.
Strict Mode
ConfigurationThe strict: true compiler option enables all strict type checking flags simultaneously: strictNullChecks, strictFunctionTypes, strictBindCallApply, strictPropertyInitialization, noImplicitAny, noImplicitThis, alwaysStrict, useUnknownInCatchVariables. New projects should always enable strict mode. Migrating: enable strict then fix errors file-by-file, or enable individual flags incrementally. Strict mode catches 10-30% more bugs than non-strict.
JSDoc Types
MigrationTypeScript can check JavaScript files using JSDoc annotations for type information. Enable with checkJs: true in tsconfig. Annotations: @type {string}, @param {number} x, @returns {boolean}, @template T (generics), @typedef, @implements. Allows gradual adoption of TypeScript checking without renaming files to .ts. VS Code provides full IntelliSense for JSDoc-typed JavaScript. Limited compared to TS syntax (no conditional types, mapped types).
Module Resolution
ConfigurationThe algorithm TypeScript uses to find imported modules. Node10 (legacy): node_modules lookup, index.js, package.json main. NodeNext: modern Node.js resolution with exports field, .mjs/.cjs distinction, and package.json conditional exports. Bundler: matches Vite/webpack resolution (no .js extension required, package.json exports). Always match moduleResolution to your runtime/bundler. Incorrect moduleResolution is the most common source of "Cannot find module" errors.
Type Erasure
Core ConceptTypeScript types are completely removed during compilation. The output JavaScript contains no type annotations, interfaces, type aliases, or generics. This means: zero runtime cost for types, no type checking at runtime, and enums/namespaces are the exception (they emit runtime code). Node.js 22+ supports --experimental-strip-types to run TypeScript directly by stripping types without full compilation. TS 5.8 erasableSyntaxOnly ensures only erasable syntax is used.
Covariance and Contravariance
Type SystemCovariance: a subtype can be used where a supertype is expected (read/output positions). Dog extends Animal means Promise<Dog> extends Promise<Animal>. Contravariance: a supertype can be used where a subtype is expected (write/input positions). Function parameters are contravariant under strictFunctionTypes. Invariance: no substitution allowed (both read and write positions). Understanding variance is essential for designing type-safe generic APIs.
Infer Keyword
Advanced TypesUsed within conditional types to extract a type. Syntax: T extends Array<infer U> ? U : never extracts the element type U from an array. Can infer in multiple positions: T extends (infer A, infer B) => infer R ? R : never. Used in all utility types: ReturnType, Parameters, ConstructorParameters, InstanceType, Awaited. Pattern: T extends SomeShape<infer Part> ? Part : Fallback. Cannot be used outside conditional types.
Triple-Slash Directive
LegacySpecial comments at the top of a file that provide compilation instructions. /// <reference types="node" /> includes type declarations for Node.js. /// <reference path="./other.ts" /> adds a file dependency. /// <reference lib="dom" /> includes a built-in library. Largely replaced by tsconfig.json types and lib options. Still used in declaration files to reference other declarations.
noUncheckedIndexedAccess
ConfigurationA compiler option that adds | undefined to all index signature access. With this enabled: const arr: number[] = [1, 2]; const x = arr[0]; // x is number | undefined (not number). Forces null checks after array/object access. Catches common bugs where the index might be out of bounds. Recommended for strict codebases. One of the most impactful strictness options not included in strict: true.
Excess Property Checking
Type SystemTypeScript checks for extra properties only on object literals assigned directly to typed variables. const user: User = { name: "X", age: 25, typo: true }; // Error: typo does not exist on User. But: const obj = { name: "X", age: 25, typo: true }; const user: User = obj; // OK (structural typing). This special-case checking catches typos in object literals, the most common source of property name errors.
Literal Types
Type SystemTypes that represent a single value. String literals: type Dir = "left" | "right". Number literals: type DiceRoll = 1 | 2 | 3 | 4 | 5 | 6. Boolean literals: true | false. Template literal types: `on${string}`. let x = "hello" infers string; const x = "hello" infers "hello" (literal). as const narrows to literal types. Literal types enable discriminated unions, exhaustive checks, and type-safe APIs.
DefinitelyTyped
EcosystemThe community repository of TypeScript type definitions for JavaScript packages that do not include their own types. Located at github.com/DefinitelyTyped. Installed via @types/package-name (e.g., @types/react, @types/node, @types/express). Over 9,000 packages. Quality varies; some definitions are incomplete. Trend: more packages ship their own types, reducing dependency on DefinitelyTyped.
Control Flow Analysis
Core ConceptTypeScript tracks variable types through code flow. After if (typeof x === "string"), x is narrowed to string. After if (x !== null), null is removed from the type. Assignment narrowing: x = "hello" narrows x to string. Return/throw narrowing: after a return or throw in an if block, the remaining code knows the condition was false. TS 5.4 preserved narrowing in closures, fixing a long-standing limitation.
Utility Types (Custom)
Advanced TypesUser-defined types that manipulate other types, extending beyond built-in utility types. Examples: DeepPartial<T> (recursive Partial), Mutable<T> (-readonly on all properties), DeepReadonly<T> (recursive Readonly), RequireAtLeastOne<T> (at least one property required from union), PathsOf<T> (all valid dot-notation paths in an object). Libraries like type-fest provide 100+ additional utility types.
Type-Safe API
PatternsAn API design where types enforce correctness at compile time. Examples: tRPC (end-to-end type safety from server to client without code generation), Prisma (database schema generates typed query builder), Zod (runtime validation that infers TypeScript types), Hono RPC (typed HTTP routes). The pattern: define the schema once, infer types everywhere. Eliminates manual type synchronization between server and client.
FAQ (20 Questions)
Try It Yourself
Convert JSON to TypeScript interfaces with our embedded tool.
Try it yourself
Json To Typescript
Tool preview unavailable.
Open Json To Typescript in a new pageRaw Data Downloads
Citations and Sources
Try These Tools for Free
Put this knowledge into practice with our browser-based tools. No signup needed.
JSON to TS
Generate TypeScript interfaces from JSON data. Handles nested objects, arrays, and optional fields.
Code Play
Write and run HTML, CSS, and JavaScript with live preview, console output, and shareable URLs.
JSON Formatter
Format, validate, and beautify JSON data with syntax highlighting.
API Tester
Test REST APIs with GET, POST, PUT, DELETE, PATCH. Custom headers, body, response viewer, and session history.
Related Research Reports
The Complete JavaScript Reference Guide 2026: Every Feature, Method & API Explained
The definitive JavaScript reference for 2026. Covers data types, functions, closures, prototypes, classes, async/await, Promises, modules, iterators, generators, Proxy/Reflect, error handling, DOM manipulation, Web APIs, and every ES2015-2026 feature. 30,000+ words with interactive charts, 39+ array methods, 28+ string methods, comparison tables, 70+ term glossary, and embedded tools.
The Complete React Guide 2026: Hooks, Server Components, Next.js, State Management & Performance
The definitive React reference for 2026. Covers hooks, Server Components, Next.js, state management, rendering patterns, performance optimization, and the React Compiler. 28,000+ words.
The Complete Angular Guide 2026: Components, Services, RxJS, NgRx, Signals & Standalone
The definitive Angular reference for 2026. Covers signals, standalone components, RxJS, NgRx, SSR, and zoneless. 42 glossary, 15 FAQ. 30,000+ words.
