Menu

TypeScript vs JavaScript: Key Differences with Examples

TypeScript is JavaScript plus a static type system that is checked before the code runs. Compare the two side by side: syntax, what the type checker catches, the build step, runtime speed, learning curve, and how to migrate a JavaScript project.

This page includes runnable editors - edit, run, and see output instantly.

TypeScript is JavaScript with a static type system added on top. Every JavaScript program is valid TypeScript syntax; TypeScript adds type annotations, a compiler that checks them before the code runs, and a build step that removes them again. At runtime there is only JavaScript, so the difference is entirely in what you find out before you ship.

In JavaScript the same function is the code minus type Product = ..., : Product[] and : number. The types add information for the compiler and the editor; they do not change what the program does.

TypeScript vs JavaScript at a Glance

JavaScriptTypeScript
Type systemDynamic: types belong to values and are only known at runtimeStatic: types are declared or inferred and checked at compile time
When type errors show upWhen the line runs (undefined, NaN, TypeError)In the editor as you type, and when you compile
Runs inBrowsers, Node.js, Deno, Bun, directlyThe same places, after the types are removed
Build stepNone neededtsc or a bundler, or a runtime that strips types itself
Files.js, .mjs, .cjs.ts, .mts, .cts, .tsx, plus .d.ts type declarations
Runtime speedBaselineIdentical: the output is JavaScript
Editor supportAutocompletion from inferred types and library typings, which can be incompleteAutocompletion, rename and "find all references" from declared types
Learning curveLowerJavaScript plus the type system
StandardECMAScript, by TC39A Microsoft open source project that tracks ECMAScript

The Same Code in Both Languages

Here is a function in JavaScript. Nothing in it says what user must look like:

function greeting(user) {
    return `Hello, ${user.firstName} ${user.lastName}`;
}

greeting({ firstname: "Ada", lastName: "Lovelace" });
// "Hello, undefined Lovelace", no error anywhere

The TypeScript version states the shape once, and the typo is reported before the code runs:

interface User {
    firstName: string;
    lastName: string;
}

function greeting(user: User): string {
    return `Hello, ${user.firstName} ${user.lastName}`;
}

greeting({ firstname: "Ada", lastName: "Lovelace" });
// error TS2561: Object literal may only specify known properties,
// but 'firstname' does not exist in type 'User'. Did you mean to write 'firstName'?

The annotations are the whole difference in syntax. TypeScript also adds a few declarations of its own (interface, type, enum, generics like Array<string>, access modifiers like private), but the statements, operators and built-in objects are JavaScript's.

What TypeScript Catches That JavaScript Does Not

JavaScript converts types silently. This bug is common with values that come from form fields, which are always strings. Run it to see what the compiler says:

index.ts(7,17): error TS2345: Argument of type 'string[]' is not assignable to parameter of type 'number[]'.
  Type 'string' is not assignable to type 'number'.

In JavaScript this runs and prints 010205, because 0 + "10" is string concatenation. TypeScript refuses to compile until the strings are converted, for example with fromForm.map(Number).

The other big category is values that might be missing. Array.prototype.find returns undefined when nothing matches, and TypeScript makes you deal with it:

index.ts(8,13): error TS18048: 'user' is possibly 'undefined'.

The plain JavaScript version crashes at runtime with TypeError: Cannot read properties of undefined (reading 'name'). The TypeScript fix is to handle the case the compiler pointed at:

Output:

GRACE
no user with id 3

What TypeScript does not catch: logic errors (a wrong formula has the right type), and anything about data that enters the program at runtime. An API response typed as User is only as correct as the server that sent it, because the types are gone once the code runs. Check such data with runtime code.

Using JavaScript Libraries in TypeScript

Every npm package works from TypeScript, because the output is JavaScript anyway. The types for a package come from one of three places:

  • The package ships its own .d.ts files. Most actively maintained packages do, and you install nothing extra.
  • A separate @types package from the community DefinitelyTyped project: npm install --save-dev @types/lodash adds types for lodash.
  • Nowhere. Then, with strict on, the import itself is an error:
error TS7016: Could not find a declaration file for module 'lodash'. '/project/node_modules/lodash/lodash.js' implicitly has an 'any' type.
  Try `npm i --save-dev @types/lodash` if it exists or add a new declaration (.d.ts) file containing `declare module 'lodash';`

The fix is to install the @types package if one exists, or to describe the module yourself in a .d.ts file; the declaration files page shows how.

The Build Step

Browsers and Node.js do not type-check, so TypeScript needs a step between your source and the code that runs. There are three common setups:

  • tsc compiles everything. It type-checks and writes .js files, usually into a dist folder. Simple, and the standard for libraries.
  • A bundler or dev server removes the types, and tsc --noEmit checks them. Vite and esbuild strip types without checking, which keeps reloads fast; the editor and a CI step run the type checker.
  • The runtime removes the types. Current Node.js versions, Deno and Bun run .ts files directly. None of them type-checks while running, so tsc --noEmit (or deno check) is still how you find type errors.

JavaScript needs none of this, which is its biggest practical advantage for small scripts. The cost of the TypeScript step is mostly setup, a tsconfig.json and a typescript dev dependency, and compile time; TypeScript 7's native compiler cut that time by about ten times on large projects.

Learning Curve

Everything you know about JavaScript carries over, because TypeScript's runtime is JavaScript. The new material is the type system, and it comes in layers:

  1. Annotations on variables, parameters and return values (: string, : number[]).
  2. Object types with interface and type, optional properties, unions like string | number.
  3. Narrowing: checking a value with typeof, in or === so the compiler knows which case you are in.
  4. Generics, utility types such as Partial<T> and Pick<T, K>, and advanced types for library authors.

The first two layers cover most application code. Much of the typing is inferred, so a lot of TypeScript looks like JavaScript with annotations only on function signatures.

When to Choose TypeScript or JavaScript

Is TypeScript better than JavaScript? For code that several people maintain or that lives for years, usually yes, and the industry has moved that way: by GitHub's count of monthly contributors, TypeScript overtook both JavaScript and Python in August 2025 to become the most used language on GitHub. For small scripts, plain JavaScript is often the better tool.

Choose TypeScript when:

  • More than one person works on the code, or it will be maintained for months or years.
  • The codebase is large enough that you cannot keep every function signature in your head.
  • You refactor often: renaming a property updates every use, and the compiler lists anything left over.
  • You publish a library: the .d.ts files give its users autocompletion and checks.
  • The framework expects it. Angular apps are written in TypeScript, Next.js and Astro scaffold new projects in TypeScript by default, and Vite's React, Vue and Svelte templates each come in a TypeScript variant.

Choose JavaScript when:

  • The program is a short script, a one-off experiment, or a code snippet in a browser console.
  • You are learning programming for the first time and want fewer concepts at once.
  • There is no build step and you do not want one. Even then, // @ts-check with JSDoc gives you some checking in a plain .js file.

Migrating a JavaScript Project to TypeScript

A migration does not have to happen at once. The compiler accepts JavaScript next to TypeScript:

{
    "compilerOptions": {
        "allowJs": true,
        "checkJs": false,
        "outDir": "dist",
        "rootDir": "src"
    },
    "include": ["src"]
}

With allowJs, .js files compile and can import from .ts files and the other way around. Then convert gradually:

  1. Rename one file from .js to .ts and fix the errors the compiler reports in it.
  2. Start with the leaves (utility modules with few imports), then work inward.
  3. Turn on checkJs, or add // @ts-check at the top of individual .js files, to type-check files you have not renamed yet.

In checked JavaScript files, JSDoc comments supply the types:

// @ts-check

/**
 * @param {number} price
 * @param {number} qty
 * @returns {number}
 */
function lineTotal(price, qty) {
    return price * qty;
}

lineTotal("3", 2);
// error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.

Some teams stop there: JavaScript files with JSDoc types, checked by tsc, and no build step for the code itself. Others go all the way to .ts. If you turn on strict in an existing project, expect many errors at first; the strict mode page lists what each flag checks so you can enable them one at a time.

Frequently Asked Questions

What is the main difference between TypeScript and JavaScript?

TypeScript adds static types to JavaScript. You describe what each value is (name: string, items: Item[]), and the TypeScript compiler reports mistakes before the code runs. JavaScript checks nothing ahead of time: a wrong type shows up only when that line executes, often as undefined or a TypeError.

Is TypeScript better than JavaScript?

For most projects that more than one person maintains, or that live longer than a few weeks, yes: types catch whole classes of bugs, make refactoring safe and power the editor's autocompletion. For a short script, a quick prototype or a learning exercise, plain JavaScript is faster to start with and needs no build setup.

Is TypeScript faster than JavaScript?

No, and it is not slower either. TypeScript compiles to JavaScript and the types are erased, so the code that runs is the same JavaScript you would write by hand. The only extra cost is compile time during development.

Should I learn JavaScript or TypeScript first?

Learn the JavaScript basics first or together with TypeScript. All runtime behavior (variables, functions, objects, arrays, promises) is JavaScript, and TypeScript only describes it. Once you can write small JavaScript programs, adding types is a short step.

Can I use TypeScript and JavaScript in the same project?

Yes. Set "allowJs": true in tsconfig.json and the compiler accepts .js files next to .ts files. Add "checkJs": true (or a // @ts-check comment per file) to type-check the JavaScript files too, using types from JSDoc comments. That is the usual way to migrate a project file by file.

Coddy programming languages illustration

Learn to code with Coddy

GET STARTED