The TypeScript language: a complete overview, pros, cons and limits

What TypeScript is for, how it differs from JavaScript, where it pays off and where it is overkill: pros and cons, TypeScript 7, a comparison with JavaScript, JSDoc, Python and Go, code examples, limits and tips.

Stack and technologies Updated

In short

TypeScript is JavaScript with types: Microsoft’s free open-source language that checks the code before it runs and then turns into ordinary JavaScript. Errors that used to surface in production — a missing field, a wrong argument, a forgotten case — are caught in the editor. It is the default for serious front ends (React, Angular, Next.js), Node.js backends, Telegram Mini Apps and browser extensions, and in TypeScript 7 the compiler was rewritten in Go and became many times faster. The catch: types exist only at build time, so data from outside still has to be validated, and over-clever types can make code harder, not easier.

TypeScript at a glance

The main facts in one table — where the language came from, how it works and where it runs.

Type
A superset of JavaScript with static typing
History
Microsoft, 2012; led by Anders Hejlsberg, the author of C#
License
Apache 2.0 — free, including commercial use
How it works
Types are checked at build time and erased: the browser gets plain JavaScript
Typing
Static and structural, with type inference
Compiler
tsc; in TypeScript 7 rewritten in Go — about ten times faster by Microsoft’s estimate
Running without a build
Node.js, Deno and Bun run .ts files by erasing the types
Compatibility
Any JavaScript library can be used; types for most come in the package or in @types
Releases
A new version roughly every three months
Popularity
The most used language on GitHub in the Octoverse 2025 report
Built with it
VS Code, Angular, the Slack and Figma front ends

What TypeScript is used for: 8 areas

Wherever JavaScript runs, TypeScript runs too. Under each area — the tools it usually comes with.

  1. 01

    Web interfaces

    Personal accounts, dashboards and complex forms: types keep hundreds of components consistent.

    ReactVueAngularSvelte

  2. 02

    Backend on Node.js

    APIs and services where the front end and the back end share types and code.

    NestJSFastifyHono

  3. 03

    Full stack in one language

    Pages, server logic and the API in one project, with types from the database to the button.

    Next.jsNuxttRPC

  4. 04

    Telegram Mini Apps and bots

    An interface inside the messenger and its bot written in one language.

    grammYTelegram SDK

  5. 05

    Browser extensions

    The extension’s pages, background script and messages between them stay in sync thanks to types.

    WXTChrome APIs

  6. 06

    Mobile apps

    One code base for iOS and Android.

    React NativeExpo

  7. 07

    Desktop apps

    Applications for Windows, macOS and Linux built with web technologies.

    ElectronTauri

  8. 08

    Edge functions

    Small handlers that run close to the user, in many data centres at once.

    Cloudflare WorkersDeno Deploy

Pros and cons of TypeScript

TypeScript trades a little ceremony for a lot of certainty. Whether the trade pays off depends on the size and lifetime of the project.

Pros · 8

  • Errors before launch

    A missing field, a wrong argument or a forgotten case is a red underline in the editor, not a bug report.

  • Safe refactoring

    Rename a field — the compiler shows every place that needs changing.

  • Smart editor

    Autocompletion, go-to-definition and inline docs work precisely because the editor knows the types.

  • Code that documents itself

    The signature says what a function takes and returns — a new developer reads it instead of guessing.

  • All of JavaScript

    Every npm library, every framework, every runtime — nothing is lost.

  • Gradual adoption

    A JavaScript project can be moved file by file, with the strictness raised step by step.

  • Shared types front to back

    Change the API — the interface that uses it does not compile until it is fixed.

  • A faster compiler

    TypeScript 7 checks large projects in seconds instead of minutes.

Cons · 8

  • No types at runtime

    After the build the types are gone: data from an API or a form must be checked by a schema such as Zod.

  • The any escape hatch

    One any switches checks off, and it spreads through the code quietly.

  • Clever types

    The type system can express almost anything — and people use it to write puzzles instead of code.

  • Configuration

    tsconfig, modules ESM and CommonJS, path aliases — the first setup still takes care.

  • Library types lag behind

    Types from @types are written separately and sometimes do not match the real library.

  • More to learn

    Generics, union types and narrowing take time for developers who came from plain JavaScript.

  • Overkill for small scripts

    A widget of fifty lines gains little from types.

  • Not faster code

    After compilation it is the same JavaScript — TypeScript buys correctness, not speed.

TypeScript compared with JavaScript, JSDoc, Python and Go

How the main ways to get types in code compare. The table shows behaviour, not benchmarks.

CriterionTypeScriptJavaScriptJS + JSDocPython + hintsGo
When errors are found in the editor and at build time at runtime in the editor, if checked by a separate checker at compile time
Types at runtime erased none none ignored enforced
Build step yes, or type stripping no no no yes
Refactoring large code safe risky safer safer safe
Runs in the browser after the build yes yes no through WebAssembly
Entry bar medium low low low medium
Best for interfaces and Node.js services small scripts libraries without a build data and AI high-load backends

When to choose TypeScript — and when not to

Twelve typical tasks with a verdict. Where TypeScript is not the best choice, the alternative is named.

  • An application interface

    Best fit

    Personal accounts, dashboards, editors — types pay off from the first month.

  • A Node.js API or service

    Best fit

    Shared types with the front end and safe refactoring.

  • Telegram Mini App

    Best fit

    The interface and the bot in one language with checked data.

  • Browser extension

    Best fit

    Messages between parts of the extension stay consistent.

  • A project with several developers

    Best fit

    Types are a contract nobody can break unnoticed.

  • A library for others

    Best fit

    Users get autocompletion and checks out of the box.

  • A content site

    Works

    The pages are built on the server; a little interactivity can live without TypeScript.

  • A prototype for a week

    Works

    Fine with loose settings; tighten them if the prototype survives.

  • A small widget or script

    Works

    JavaScript with JSDoc gives hints without a build.

  • Data analysis and ML

    Pick another

    Python: the libraries and notebooks are there.

  • Very high load

    Pick another

    Go or Rust: compiled code and real types at runtime.

  • Heavy computing in the browser

    Pick another

    Rust or C++ compiled to WebAssembly.

The TypeScript ecosystem: tools for common tasks

The compiler checks types; everything else comes from the JavaScript world, now with types.

TaskTools
Type checking tsc
Running .ts files node, tsx, Deno, Bun
Building for the browser Vite, esbuild, Rolldown
Checking external data Zod, Valibot, ArkType
Typed database access Drizzle, Prisma, Kysely
Typed API tRPC, openapi-typescript
Linting typescript-eslint, Biome
Formatting Prettier, Biome
Tests Vitest, node:test, Playwright
Frameworks React, Next.js, Angular, NestJS
Types for JS libraries @types/*

The limits of TypeScript: where it does not protect

  1. Data from outside

    A response from an API, a form or a file has the type you wrote, not the type it really has. Without a schema the check is a promise.

  2. Type assertions

    as SomeType tells the compiler “trust me” — and it does, even when you are wrong.

  3. any inside libraries

    A weakly typed dependency lets any into a strictly typed project through the back door.

  4. Very complex types

    Deep conditional and recursive types slow the editor down and cannot be read by the next developer.

  5. Speed

    TypeScript does not make code faster: performance is decided by JavaScript and the runtime.

  6. Modules

    Mixing ESM and CommonJS is still the most common source of setup pain.

8 tips for TypeScript that actually protects

  1. 01

    strict from day one

    Turning strictness on later costs hundreds of fixes; at the start it costs nothing.

  2. 02

    noUncheckedIndexedAccess

    Reading an array element or a map key may return nothing — the compiler should know it.

  3. 03

    Validate input with a schema

    Zod or Valibot at every border: API, forms, files, environment variables.

  4. 04

    unknown instead of any

    unknown forces you to check before use; any silently switches everything off.

  5. 05

    Unions instead of enums

    'new' | 'paid' erases cleanly and works with type stripping; enum does not.

  6. 06

    Let types be inferred

    Annotate function borders; inside, inference is precise and code stays short.

  7. 07

    Generate types, do not copy them

    From the database schema and the OpenAPI description — then they never drift apart.

  8. 08

    Simple types beat clever ones

    If a type needs a comment to be understood, it is probably too clever.

What TypeScript looks like: 3 examples

Three examples behind the main strengths: the compiler catching a forgotten case, checking data from outside and types that follow the code. Checked by TypeScript 7 in strict mode and run in Node.js.

A forgotten case is a compile error

Each status has its own fields, and adding a new status without handling it does not compile.

order.ts
// an order status is one of several shapes, and each shape has its own fields
type Order =
  | { status: 'new' }
  | { status: 'paid'; paidAt: Date }
  | { status: 'shipped'; trackingCode: string };

function describe(order: Order): string {
  switch (order.status) {
    case 'new':
      return 'Awaiting payment';
    case 'paid':
      return `Paid on ${order.paidAt.toISOString().slice(0, 10)}`;
    case 'shipped':
      return `On the way: ${order.trackingCode}`; // trackingCode exists only here
    default: {
      // a new status added to Order and forgotten here is a compile error
      const unhandled: never = order;
      return unhandled;
    }
  }
}

console.log(describe({ status: 'shipped', trackingCode: 'RA123' })); // On the way: RA123

Checking data from outside

A Zod schema checks the real data and gives the type at the same time.

parse.ts
import { z } from 'zod';

// types disappear after compilation, so data from outside is checked by a schema
const Order = z.object({
  id: z.number().int().positive(),
  email: z.email(),
  total: z.number().nonnegative(),
});
type Order = z.infer<typeof Order>; // the type is derived from the schema, no duplication

const fromApi: unknown = JSON.parse('{"id": 7, "email": "[email protected]", "total": -5}');

const result = Order.safeParse(fromApi);
if (result.success) {
  const order: Order = result.data;
  console.log(order.total);
} else {
  console.log(result.error.issues[0]?.path); // [ 'total' ]
}

Generics and satisfies

One function works for any data and keeps its types; satisfies checks the shape without losing exact values.

plans.ts
// a generic function: the result type follows the input
function groupBy<T, K extends PropertyKey>(items: readonly T[], key: (item: T) => K): Record<K, T[]> {
  const groups = {} as Record<K, T[]>;
  for (const item of items) {
    (groups[key(item)] ??= []).push(item);
  }
  return groups;
}

// satisfies checks the shape but keeps the exact values
const plans = {
  start: { price: 0, seats: 1 },
  team: { price: 29, seats: 10 },
} satisfies Record<string, { price: number; seats: number }>;

type Plan = keyof typeof plans; // 'start' | 'team', not just string

const users = [
  { name: 'Anna', plan: 'team' as Plan },
  { name: 'Oleg', plan: 'start' as Plan },
  { name: 'Ira', plan: 'team' as Plan },
];
const byPlan = groupBy(users, (u) => u.plan);
console.log(byPlan.team?.length, plans.team.price); // 2 29

Questions about TypeScript

What is the difference between TypeScript and JavaScript?

TypeScript is JavaScript plus types that are checked before the code runs. After the build it becomes ordinary JavaScript.

Does a small project need TypeScript?

A script of fifty lines — no. Anything that will live and grow — yes: types pay off at the first refactoring.

Is it hard to move a project from JavaScript?

No: TypeScript accepts JavaScript files, so the move goes file by file, raising strictness gradually.

Does TypeScript slow development down?

A little at the start, a lot less later: fewer bugs, faster refactoring and less time spent figuring out what code does.

Does the browser run TypeScript?

No, the browser runs JavaScript. A bundler such as Vite strips the types; Node.js, Deno and Bun can do it on the fly.

What is new in TypeScript 7?

The compiler was rewritten in Go: by Microsoft’s estimate, about ten times faster, with the same language.

Does TypeScript make code faster?

No. It makes code more correct; the speed is the same as JavaScript’s.

TypeScript or JSDoc?

JSDoc gives types in comments without a build — fine for small libraries. For applications TypeScript is more convenient and stricter.

Is TypeScript used on the backend?

Yes, with Node.js, Deno and Bun — especially when the front end and back end share types.

Online form

Development
in TypeScript

I build interfaces and services in TypeScript: React applications, personal accounts, Telegram Mini Apps and browser extensions — strict types, fast builds and code your team can pick up. Tell me about the task — I answer within one working day.

Or write to [email protected]