Chapter 10: The TypeScript Ecosystem

TypeScript isn’t just a compiler. It’s a thriving ecosystem of tools, libraries, frameworks, and patterns that have evolved around it.

This chapter surveys the landscape: what works well with TypeScript, what requires extra configuration, and where the community is heading.

Frameworks and Libraries

React

TypeScript and React are a natural pair. React’s component model maps cleanly to TypeScript’s type system.

interface ButtonProps {
  label: string;
  onClick: () => void;
  disabled?: boolean;
}

function Button({ label, onClick, disabled = false }: ButtonProps) {
  return (
    <button onClick={onClick} disabled={disabled}>
      {label}
    </button>
  );
}

Key packages:

Setup:

{
  "compilerOptions": {
    "jsx": "react-jsx",
    "lib": ["ES2020", "DOM"]
  }
}

More in Chapter 12.

Vue

Vue 3 is written in TypeScript and has first-class support:

import { defineComponent } from 'vue';

export default defineComponent({
  props: {
    message: {
      type: String,
      required: true
    }
  },
  setup(props) {
    return {
      uppercased: props.message.toUpperCase()
    };
  }
});

Setup:

npm create vue@latest # Choose TypeScript

Angular

Angular is TypeScript-first. It was designed with TypeScript from the start:

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  template: `<h1></h1>`
})
export class AppComponent {
  title: string = 'Hello Angular';
}

No extra setup needed. Angular CLI handles everything.

Svelte

Svelte has TypeScript support via svelte-check:

<script lang="ts">
  export let name: string;
  let count: number = 0;

  function increment() {
    count += 1;
  }
</script>

<button on:click={increment}>
  Clicked {count} times by {name}
</button>

Setup:

npm create vite@latest my-app -- --template svelte-ts

Node.js

Node.js with TypeScript requires configuration:

npm install --save-dev typescript @types/node ts-node
npx tsc --init

Or use Deno/Bun for zero-config TypeScript.

Key packages:

Express

npm install express
npm install --save-dev @types/express
import express, { Request, Response } from 'express';

const app = express();

app.get('/users/:id', (req: Request, res: Response) => {
  const userId = req.params.id;
  res.json({ id: userId, name: 'Alice' });
});

app.listen(3000);

Fastify

Fastify has built-in TypeScript support:

import Fastify from 'fastify';

const server = Fastify();

server.get('/ping', async (request, reply) => {
  return { pong: 'it worked!' };
});

server.listen({ port: 3000 });

NestJS

A TypeScript-first Node.js framework (Angular-inspired):

import { Controller, Get } from '@nestjs/common';

@Controller('users')
export class UsersController {
  @Get()
  findAll(): string {
    return 'This returns all users';
  }
}

Built for TypeScript. Decorators, dependency injection, modular architecture.

Prisma

Type-safe ORM with generated types:

import { PrismaClient } from '@prisma/client';

const prisma = new PrismaClient();

const user = await prisma.user.findUnique({
  where: { id: 1 }
});
// user is fully typed based on your schema

Prisma generates TypeScript types from your database schema. Changes to the schema automatically update types.

GraphQL

Type-safe GraphQL clients and servers:

Apollo Client:

npm install @apollo/client graphql

GraphQL Code Generator:

npm install --save-dev @graphql-codegen/cli

Generates TypeScript types from GraphQL schemas:

# codegen.yml
schema: 'http://localhost:4000/graphql'
documents: 'src/**/*.graphql'
generates:
  src/generated/graphql.ts:
    plugins:
      - typescript
      - typescript-operations

Build Tools

Vite

Modern, fast, zero-config TypeScript support:

npm create vite@latest my-app -- --template vanilla-ts

Just works. No tsconfig tweaking needed (mostly).

Webpack

Mature, configurable, requires setup:

npm install --save-dev typescript ts-loader
// webpack.config.js
module.exports = {
  module: {
    rules: [
      {
        test: /\.ts$/,
        use: 'ts-loader',
        exclude: /node_modules/
      }
    ]
  }
};

esbuild

Extremely fast bundler and transpiler:

npm install --save-dev esbuild
esbuild src/index.ts --bundle --outfile=dist/index.js

Important: esbuild doesn’t type-check. Run tsc --noEmit separately.

Rollup

Flexible bundler, often used for libraries:

npm install --save-dev rollup @rollup/plugin-typescript
// rollup.config.js
import typescript from '@rollup/plugin-typescript';

export default {
  input: 'src/index.ts',
  output: {
    file: 'dist/index.js',
    format: 'esm'
  },
  plugins: [typescript()]
};

Turbopack (Next.js)

Next.js 13+ uses Turbopack (Rust-based). TypeScript support is built-in:

npx create-next-app@latest --typescript

Parcel

Zero-config bundler:

npm install --save-dev parcel
parcel src/index.html

Detects TypeScript automatically. No config needed.

Testing Frameworks

Jest

Popular, mature, requires configuration:

npm install --save-dev jest ts-jest @types/jest
// jest.config.js
module.exports = {
  preset: 'ts-jest',
  testEnvironment: 'node'
};
// math.test.ts
import { add } from './math';

test('adds numbers', () => {
  expect(add(2, 3)).toBe(5);
});

Vitest

Modern, Vite-powered, zero-config:

npm install --save-dev vitest
// math.test.ts
import { describe, it, expect } from 'vitest';
import { add } from './math';

describe('add', () => {
  it('adds numbers', () => {
    expect(add(2, 3)).toBe(5);
  });
});

TypeScript support built-in. Extremely fast.

Testing Library

UI testing with full TypeScript support:

npm install --save-dev @testing-library/react @testing-library/jest-dom
import { render, screen } from '@testing-library/react';
import Button from './Button';

test('renders button', () => {
  render(<Button label="Click me" onClick={() => {}} />);
  expect(screen.getByText('Click me')).toBeInTheDocument();
});

Playwright

End-to-end testing with TypeScript:

npm install --save-dev @playwright/test
import { test, expect } from '@playwright/test';

test('homepage has title', async ({ page }) => {
  await page.goto('http://localhost:3000');
  await expect(page).toHaveTitle(/My App/);
});

Cypress

npm install --save-dev cypress
// cypress/e2e/spec.cy.ts
describe('My App', () => {
  it('visits the homepage', () => {
    cy.visit('http://localhost:3000');
    cy.contains('Welcome');
  });
});

Linters and Formatters

ESLint

npm install --save-dev eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin
// .eslintrc.js
module.exports = {
  parser: '@typescript-eslint/parser',
  plugins: ['@typescript-eslint'],
  extends: [
    'eslint:recommended',
    'plugin:@typescript-eslint/recommended'
  ]
};

Prettier

npm install --save-dev prettier
// .prettierrc
{
  "semi": true,
  "singleQuote": true,
  "trailingComma": "es5"
}

Biome

Modern all-in-one linter/formatter (Rust-based):

npm install --save-dev @biomejs/biome
npx biome check .
npx biome format --write .

Extremely fast. Alternative to ESLint + Prettier.

Runtime Validation

TypeScript types are compile-time only. Runtime validation requires separate tools:

Zod

Schema validation with TypeScript inference:

import { z } from 'zod';

const UserSchema = z.object({
  id: z.string(),
  name: z.string(),
  age: z.number()
});

type User = z.infer<typeof UserSchema>;
// { id: string; name: string; age: number; }

const data = JSON.parse(apiResponse);
const user = UserSchema.parse(data); // Throws if invalid

Yup

Similar to Zod:

import * as yup from 'yup';

const userSchema = yup.object({
  name: yup.string().required(),
  age: yup.number().positive().required()
});

await userSchema.validate({ name: 'Alice', age: 30 });

io-ts

Functional approach:

import * as t from 'io-ts';

const User = t.type({
  id: t.string,
  name: t.string,
  age: t.number
});

type User = t.TypeOf<typeof User>;

AJV

JSON Schema validator:

import Ajv from 'ajv';

const ajv = new Ajv();
const schema = {
  type: 'object',
  properties: {
    name: { type: 'string' },
    age: { type: 'number' }
  },
  required: ['name', 'age']
};

const validate = ajv.compile(schema);
const valid = validate(data);

Documentation

TSDoc

JSDoc for TypeScript:

/**
 * Calculates the sum of two numbers.
 * @param a - The first number
 * @param b - The second number
 * @returns The sum of a and b
 * @example
 * ```ts
 * add(2, 3); // 5
 * ```
 */
function add(a: number, b: number): number {
  return a + b;
}

VSCode shows this in IntelliSense.

TypeDoc

Generate docs from TypeScript code:

npm install --save-dev typedoc
npx typedoc --out docs src/index.ts

Creates HTML documentation from your types and TSDoc comments.

Package Managers

npm

Standard. Ships with Node.js:

npm install typescript

pnpm

Fast, disk-efficient:

pnpm install typescript

Uses symlinks, saves disk space, faster installs.

Yarn

Alternative to npm:

yarn add typescript

Yarn 2+ (Berry) has workspaces, Plug’n’Play mode.

Bun

Extremely fast (native code):

bun install typescript

Also runs TypeScript natively (bun run script.ts).

Monorepo Tools

Turborepo

Fast build system for monorepos:

npx create-turbo@latest

Caches builds, runs tasks in parallel. TypeScript-aware.

Nx

Powerful monorepo tool:

npx create-nx-workspace

Supports TypeScript out of the box. Dependency graph, affected commands, caching.

Lerna

Classic monorepo manager:

npx lerna init

Less popular now. Turborepo and Nx are more modern.

Deployment

Vercel

Zero-config deployments for TypeScript:

npm install -g vercel
vercel

Supports Next.js, Vite, vanilla TypeScript. Detects TypeScript automatically.

Netlify

Similar to Vercel:

npm install -g netlify-cli
netlify deploy

Deno Deploy

Deploy TypeScript directly to the edge:

deployctl deploy --project=my-project server.ts

No build step. TypeScript runs in production.

Cloudflare Workers

Supports TypeScript via Wrangler:

npm install -g wrangler
wrangler init
// worker.ts
export default {
  async fetch(request: Request): Promise<Response> {
    return new Response('Hello from TypeScript!');
  }
};

AWS Lambda

Use AWS CDK or Serverless Framework:

npm install -g aws-cdk
cdk init app --language typescript

Editor Support

VS Code

Best-in-class TypeScript support. Built by the same team (Microsoft).

Extensions:

WebStorm

Full IDE with built-in TypeScript support. No extensions needed.

Neovim/Vim

Use coc.nvim or native LSP with typescript-language-server:

npm install -g typescript-language-server

Emacs

Use lsp-mode or tide:

npm install -g typescript-language-server

Community Resources

TypeScript Handbook

Official docs: typescriptlang.org/docs

Comprehensive. Start here.

TypeScript Deep Dive

Free online book by Basarat Ali Syed. Practical, example-driven.

Effective TypeScript

Book by Dan Vanderkam. 62 specific tips for better TypeScript.

Total TypeScript

Video course by Matt Pocock. Interactive, exercise-based.

TypeScript Playground

typescriptlang.org/play

Test code snippets, share examples, explore compiler options.

GitHub Issues

github.com/microsoft/TypeScript/issues

Report bugs, request features, see what’s coming.

Twitter/X

Follow:

Emerging Patterns

Type-Safe SQL

Kysely:

const result = await db
  .selectFrom('users')
  .select(['id', 'name'])
  .where('age', '>', 18)
  .execute();
// result is typed based on schema

Drizzle:

const users = await db.select().from(usersTable).where(eq(usersTable.age, 30));
// Fully typed

Type-Safe APIs

tRPC:

const user = await trpc.user.getById.query({ id: '123' });
// user is typed, no code generation needed

Full-stack type safety. Client knows server types automatically.

Effect-TS

Functional programming library with powerful type system:

import { Effect } from 'effect';

const program = Effect.gen(function* (_) {
  const user = yield* _(fetchUser('123'));
  return user.name;
});

Advanced. Steep learning curve. Growing community.

What You’ve Learned

The TypeScript ecosystem is mature. Most tools you already use support it. New tools are being built TypeScript-first.


Next: Chapter 11: Migrating JavaScript to TypeScript