TypeScript for Beginners — Why Every Developer Needs It

Photo: Daniil Komov / Pexels
TypeScript is JavaScript with a checker bolted on. You write the same language, add small annotations that describe what your values are supposed to be, and a compiler reads the whole program before anything runs and reports where the descriptions and the code disagree. In the 2025 Stack Overflow Developer Survey, 48.8% of professional developers reported using it, and GitHub's Octoverse report ranked it the most-used language on the platform in August 2025. This article explains what it does, where it stops helping, and how to start.
What TypeScript actually is
The official handbook puts it plainly: TypeScript "checks a program for errors before execution, and does so based on the kinds of values, making it a static type checker." It also describes the language as "a superset of JavaScript: JS syntax is therefore legal TS." In other words, you are not learning a new language from zero. You are learning a vocabulary for describing the JavaScript you already write.
Here is the smallest useful example:
// JavaScript
function greet(name) {
return "Hello, " + name;
}
// TypeScript
function greet(name: string): string {
return "Hello, " + name;
}
The TypeScript version says the function takes a string and returns a string. Now call it with the wrong thing:
greet(42); // Error: Argument of type 'number' is not assignable to parameter of type 'string'
The editor underlines that line the moment you type it. In plain JavaScript the same call would run happily and produce "Hello, 42", which is wrong in a way nobody notices until a user sees it.
A useful analogy is a building inspection. JavaScript is a house you can move into the day the last nail goes in. TypeScript sends an inspector through first, with a checklist you wrote yourself (the types), and the inspector reports every outlet that is not connected to the wire you said it was. The inspector never changes the house. It only tells you what it found.
What happens to the types afterward
The types do not survive into the running program. The handbook is direct about this: once the compiler is done checking, it erases the types to produce plain JavaScript, so "the resulting plain JS code has no type information." It adds that TypeScript "never changes the behavior of your program based on the types it inferred," and that moving code from JavaScript to TypeScript is guaranteed to run the same way "even if TypeScript thinks that the code has type errors."
Two consequences follow, and beginners trip over both. First, there is no performance cost at runtime, because the browser or server never sees a type. Second, there is no protection at runtime either. A type annotation is a promise you make to the checker, not a guard the program enforces. We return to that gap in a later section, because it is where most real-world TypeScript bugs hide.
Is every JavaScript file valid TypeScript?
Almost, with a catch worth understanding. The syntax is always legal, so the compiler will not reject JavaScript for being malformed. But legal syntax can still contain type errors. The handbook's own example is console.log(4 / []), which JavaScript runs and prints Infinity, while TypeScript complains that the right-hand side of an arithmetic operation must be a number, bigint, enum, or any. The program still compiles and runs the same way. The checker is telling you the code is suspicious, not stopping it.
Why TypeScript won the adoption race
Popularity numbers are easy to overstate, so here are the two that come from primary surveys, with their labels intact.
| Source | Measure | TypeScript | JavaScript | Python |
|---|---|---|---|---|
| Stack Overflow Developer Survey 2025 | All respondents | 43.6% | 66% | 57.9% |
| Stack Overflow Developer Survey 2025 | Professional developers | 48.8% | 68.8% | 54.8% |
The Stack Overflow question counts who used a language in the past year, so JavaScript still leads, which makes sense: every TypeScript developer is also writing JavaScript semantics. The GitHub figure measures something different. Octoverse ranks languages by distinct monthly contributors, and for August 2025 it put TypeScript first, with 2,636,006 contributors, ahead of Python and JavaScript. That was 66.63% more than a year earlier. GitHub's own write-up notes that other indexes use different methods and may still rank JavaScript or Python higher.
GitHub offered several explanations for the climb, and they are more interesting than the ranking. Many frameworks now scaffold new projects in TypeScript by default, including Next.js 15, Astro 3, SvelteKit 2, and Angular 18. Tools such as Vite, Bun, and automatic editor configuration have lowered the setup cost. Some activity that used to be counted as JavaScript was already passing through TypeScript pipelines. And GitHub argues that stricter type systems suit AI-assisted coding, because types catch a class of machine-generated mistakes early. It cites an academic study finding that 94% of LLM-generated compilation errors were type-check failures. That is an external study, not GitHub's own measurement, and it describes compile errors specifically, not overall code quality.
This is the point where it is worth separating "popular" from "necessary." A ranking does not tell you whether a given project should adopt TypeScript. What the numbers do tell you is practical: most tutorials, templates, and library documentation you meet in web development now assume it, so not reading it is a handicap even if you decide to write plain JavaScript.
The problems types solve
JavaScript is dynamically typed. A variable can hold a number now and an object later, and types only matter when the code runs. That flexibility is fine for a 50-line script. It becomes expensive as a codebase grows, in four specific ways.
Refactoring becomes guesswork. Rename a function in JavaScript and you hope your text search found every call. Rename it in TypeScript and the compiler lists every place that broke.
Interfaces become folklore. What does this function return? Is user.email always a string, or can it be missing? In JavaScript the answer lives in someone's head or a stale comment. In TypeScript the answer is in the signature, and your editor shows it on hover.
Typos survive. The handbook's example is obj.heigth instead of obj.height. JavaScript quietly returns undefined and multiplication turns it into NaN. TypeScript reports "Property 'heigth' does not exist" and suggests the correct spelling.
Autocomplete is blind. Without types, an editor has to guess which properties an object has. With types, it knows, so completion, documentation popups, and jump-to-definition all work.
The cost is real but modest: more syntax, and a compile step (usually handled by your framework or build tool). The payoff grows with project size and team size, and it is smallest for throwaway scripts. A 200-line personal script may not need it. A product that five people touch for three years does.
TypeScript basics you need first
Type annotations
An annotation is a colon and a type after a name:
let age: number = 30;
let name: string = "Alice";
let isActive: boolean = true;
let scores: number[] = [85, 92, 78];
let user: { name: string; age: number } = { name: "Alice", age: 30 };
function calculate(a: number, b: number): number {
return a + b;
}
function greet(name: string, greeting?: string): string {
return `${greeting ?? "Hello"}, ${name}`;
}
The question mark after greeting marks it optional. Inside the function its type is string | undefined, and the compiler makes you handle both cases before using it as a string.
Type inference
You do not annotate everything. TypeScript works out types from the values you assign:
let count = 0; // inferred as number
const numbers = [1, 2, 3]; // inferred as number[]
function double(n: number) {
return n * 2; // return type inferred as number
}
A common rule of thumb: annotate function parameters and the return types of exported functions, and let inference handle local variables. Parameters need annotations because the compiler has no values to learn from. Exported return types are worth stating because they form a contract other files depend on, and a stated type stops an accidental change inside the function from silently changing the contract.
Type aliases and interfaces
Name a shape once and reuse it:
type User = {
id: string;
name: string;
email: string;
age?: number; // optional
};
interface Product {
id: string;
name: string;
price: number;
inStock: boolean;
}
For plain object shapes the two are close to interchangeable. Interfaces can be extended and merged across declarations, while type can also describe unions, tuples, and primitives. Many teams pick one for objects and stick with it. Consistency matters more than the choice.
Union types and literal types
A union says a value can be one of several things:
type Status = "pending" | "active" | "cancelled";
function setStatus(status: Status) {
// only those three strings are accepted
}
function formatId(id: number | string): string {
return `ID-${id}`;
}
function findUser(id: string): User | null {
// may return nothing
return null;
}
The string-literal union is one of the most useful beginner features. It replaces a loose string with a closed list, so a typo like "cancled" becomes a compile error instead of a bug in the database.
Generics
Generics let one function or type work across many types while remembering which one it was given. Think of a labeled storage box: the box design is the same, but the label says what is inside, and the label follows the contents out.
function firstElement<T>(arr: T[]): T | undefined {
return arr[0];
}
const num = firstElement([1, 2, 3]); // number | undefined
const str = firstElement(["a", "b", "c"]); // string | undefined
type Result<T> = {
data: T | null;
error: string | null;
};
The T is a placeholder, filled in at each call. Libraries use generics so that useState<number>(0) or a typed API client can offer flexible functions that still know exactly what they return.
Narrowing: how the compiler learns what a value is
Union types raise an obvious question. If a value is string | number, what can you do with it? The answer is that you check, and the compiler tracks the check. This is called narrowing.
function processInput(value: string | number) {
if (typeof value === "string") {
return value.toUpperCase(); // value is a string here
}
return value * 2; // value is a number here
}
Inside the if, the compiler knows value is a string, so string methods are allowed. After it, only a number can remain. This flow-sensitive reasoning is what makes unions practical and not a nuisance.
Discriminated unions
The pattern that pays off fastest in real applications is a union where every member carries a shared "tag" field. Loading state is the classic case:
type LoadingState = { status: "loading" };
type SuccessState<T> = { status: "success"; data: T };
type ErrorState = { status: "error"; error: string };
type State<T> = LoadingState | SuccessState<T> | ErrorState;
function describe<T>(state: State<T>): string {
switch (state.status) {
case "loading":
return "Loading...";
case "success":
return `Got ${JSON.stringify(state.data)}`; // data exists only here
case "error":
return `Failed: ${state.error}`; // error exists only here
}
}
Without this pattern, state is usually modeled as three optional fields that can contradict each other: loading: true and error: "boom" at the same time, for instance. A discriminated union makes the impossible combinations unrepresentable. If you later add a fourth status, the compiler points at every switch that forgot to handle it.
Custom type guards and the unknown type
Sometimes you need your own check, especially for data that arrives from outside your program:
function isUser(obj: unknown): obj is User {
return (
typeof obj === "object" && obj !== null &&
typeof (obj as User).id === "string" &&
typeof (obj as User).email === "string"
);
}
const data: unknown = JSON.parse(rawText);
if (isUser(data)) {
console.log(data.email); // typed as User here
}
unknown is the safe cousin of any. A value typed unknown can hold anything, but the compiler refuses to let you use it until you have narrowed it. A value typed any switches the checker off for everything that touches it. That difference is the whole reason the "avoid any" advice exists.
Utility types
TypeScript ships helpers that derive new types from existing ones:
type UserUpdate = Partial<User>; // every property optional
type UserSummary = Pick<User, "id" | "name">; // only these properties
type PublicUser = Omit<User, "email">; // everything except email
type FullUser = Required<User>; // every property required
type FrozenUser = Readonly<User>; // no reassignment
These save you from copy-pasting near-identical types, and they keep derived types in sync. Change User once and UserSummary and PublicUser follow.
Strict mode: the setting that decides how useful TypeScript is
The strict option in tsconfig.json is not one check. The TypeScript reference describes it as turning on a family of flags: alwaysStrict, strictNullChecks, strictBindCallApply, strictBuiltinIteratorReturn, strictFunctionTypes, strictPropertyInitialization, noImplicitAny, noImplicitThis, and useUnknownInCatchVariables. Two of them do most of the work for beginners.
| Flag | What it stops | Example it catches |
|---|---|---|
noImplicitAny |
The compiler silently falling back to any when it cannot infer a type |
A function parameter with no annotation: function fn(s) { s.subtr(3) } |
strictNullChecks |
Treating null and undefined as values that can sit in any type |
users.find(...) returns something possibly undefined, then code reads .age from it |
The strictNullChecks example from the official reference is worth remembering. users.find(...) returns undefined when nothing matches. With the flag off, the type system pretends find always returns a user, so loggedInUser.age compiles and then crashes in production. With the flag on, the compiler says 'loggedInUser' is possibly 'undefined' and makes you decide what to do about it.
The same reference notes that future TypeScript versions may add stricter checks under strict, so upgrading can surface new errors, and that individual strict-family checks can be switched off one at a time. Treat strict: true as the default for new code. For an existing JavaScript project being migrated, the individual flags give you a way to tighten gradually.
Strict becomes the default in TypeScript 7
This matters for what you will see in new projects. According to InfoQ's report on the release, TypeScript 7.0 turns the deprecations introduced in 6.0 into hard errors and makes strict and esnext the defaults. If you are following older tutorials that tell you to remember to add strict: true, newer compilers will already have done it. The habit is still worth knowing, because many existing projects are on older versions or have explicit settings.
TypeScript with React
React is where most beginners meet TypeScript, and the main idea is simple: props are a typed contract between a parent and a child.
type ButtonProps = {
label: string;
onClick: () => void;
variant?: "primary" | "secondary";
disabled?: boolean;
};
function Button({ label, onClick, variant = "primary", disabled = false }: ButtonProps) {
return (
<button
onClick={onClick}
disabled={disabled}
className={variant === "primary" ? "btn-primary" : "btn-secondary"}
>
{label}
</button>
);
}
// Usage: a typo in a prop name or a missing label is a compile error
<Button label="Save" onClick={() => console.log("saved")} variant="primary" />
If someone passes variant="tertiary", the editor flags it. If someone forgets label, the editor flags that too. Compare that with a JavaScript component, where a missing prop becomes the string undefined rendered in the middle of the page.
Patterns you will use daily
// State with an explicit type when inference needs help
const [count, setCount] = useState<number>(0);
const [user, setUser] = useState<User | null>(null);
// Event handlers
function handleChange(e: React.ChangeEvent<HTMLInputElement>) {
setName(e.target.value);
}
function handleSubmit(e: React.FormEvent) {
e.preventDefault();
}
// Refs start as null until React attaches the element
const inputRef = useRef<HTMLInputElement>(null);
// A typed custom hook
function useFetch<T>(url: string): { data: T | null; loading: boolean } {
// ...
return { data: null, loading: true };
}
The User | null state is a good illustration of why strict null checks matter. The first render has no user yet, so the type says so, and every component that reads user.name must check for null first. In a JavaScript codebase, this exact oversight is one of the most common sources of the "cannot read properties of null" crash.
If you are choosing a stack, our comparison of Next.js and React in 2026 explains how the frameworks scaffold TypeScript for you, and the Next.js 15 developer's guide walks through typed Server Components and routing. For state management with good type inference, see Zustand vs Redux.
Setting up a project
The easy route: let a scaffold do it
npx create-next-app@latest my-app --typescript
npm create vite@latest my-app -- --template react-ts
Both commands generate a working tsconfig.json. Vite deserves a closer look, because its documentation states that it "only performs transpilation on .ts files and does NOT perform type checking." Our explainer on Vite covers the tool itself; the consequence for your workflow is spelled out just below.
Adding TypeScript to an existing JavaScript project
npm install -D typescript @types/node @types/react
npx tsc --init
Then rename files from .js to .ts (or .tsx for files with JSX) a few at a time. TypeScript can handle JavaScript and TypeScript files side by side, so you do not need to convert everything at once. With the allowJs option you can import JavaScript from TypeScript while you migrate.
A reasonable starting tsconfig.json:
{
"compilerOptions": {
"target": "ES2022",
"lib": ["DOM", "DOM.Iterable", "ES2022"],
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"module": "ESNext",
"moduleResolution": "Bundler",
"jsx": "preserve",
"noEmit": true
},
"include": ["src/**/*"],
"exclude": ["node_modules"]
}
noEmit: true tells tsc to check types but write no files, which is what you want when a bundler such as Vite or Next.js handles the actual JavaScript output. skipLibCheck skips type-checking of declaration files inside node_modules, a trade-off that speeds up builds and hides some third-party type conflicts.
Checking and building are separate jobs
Many modern tools turn TypeScript into JavaScript by removing the annotations, without checking them. Your dev server can therefore run happily while tsc --noEmit would report a dozen errors. Vite's documentation recommends running tsc --noEmit in addition to the build for production, and tsc --noEmit --watch in a separate process during development. The same logic applies in continuous integration before a merge. Treat "it ran" and "it type-checks" as two separate questions.
TypeScript 7 and the native compiler
The standard compiler, tsc, was itself written in TypeScript and ran on Node.js. Microsoft ported it to Go. According to InfoQ, the native port began as an experimental preview in March 2025 and InfoQ reported the stable release of TypeScript 7.0, the first to include it, on August 3, 2026.
What matters to a beginner is speed and one caveat.
| Item | Reported detail (InfoQ, August 2026) |
|---|---|
| Typical speedup on full builds | 8x to 12x, per Microsoft |
| VS Code full build | 125.7 seconds on TypeScript 6, 10.6 seconds on 7.0 |
| Opening a file with an error in VS Code | About 17.5 seconds down to under 1.3 seconds |
| Slack CI type-checking | About 7.5 minutes down to 1.25 minutes |
| Caveat | No stable programmatic API in 7.0; the team expects one in 7.1 |
The caveat explains why some tools lag. Linters such as typescript-eslint, framework tooling, and webpack loaders depend on the old programmatic API. A compatibility package, @typescript/typescript6, re-exports the 6.0 API so existing tooling can run side by side, and the team recommends adopting 6.0 first before moving to 7.0. These benchmarks are Microsoft's and users' own reports on large codebases, so a small project will see smaller absolute gains because there was little waiting to begin with.
Running TypeScript without a build step
Another shift worth knowing about: Node.js can now run TypeScript files directly. The Node documentation describes how it works, and the details are narrower than the headline suggests.
- Node runs files that contain only erasable TypeScript syntax. It replaces type annotations with whitespace and performs no type checking.
- The feature was added in v22.6.0, enabled by default in v22.18.0 and v23.6.0, and documented as stable from v25.2.0 and v24.12.0.
- Node ignores
tsconfig.json, so settings such aspathsdo not apply. - Syntax that needs real code generation fails, including
enumdeclarations, namespaces that contain runtime values, and constructor parameter properties. - Imports of types need the
typekeyword, and file extensions are mandatory (./file.ts).
Node's docs recommend TypeScript 5.8 or newer with erasableSyntaxOnly enabled, which makes the compiler warn you when you write syntax that Node cannot strip. For anything beyond that subset, the docs point to third-party tools such as tsx.
For a beginner, the practical lesson is to prefer a union of string literals over an enum. It does the same job, works everywhere, and survives type stripping. That is a small example of how the language is shifting toward syntax that can be erased.
TypeScript on the server
The same typing ideas apply on a backend:
import express, { Request, Response } from "express";
const app = express();
app.get("/users/:id", async (req: Request, res: Response) => {
const user = await getUserById(req.params.id);
if (!user) {
return res.status(404).json({ error: "Not found" });
}
res.json(user);
});
The compiler knows req.params.id is a string and that res.json accepts a value to serialize. It does not know what shape getUserById returns unless that function is typed too, which is why types need to run through the whole call chain to be worth much.
End-to-end types with tRPC
Frameworks such as Hono, Elysia, and tRPC push this further. In tRPC, the server declares a procedure and its input schema, and the client imports the inferred types, so changing a server field breaks client code at compile time:
const appRouter = t.router({
getUser: t.procedure
.input(z.object({ id: z.string() }))
.query(async ({ input }) => {
return await db.user.findUnique({ where: { id: input.id } });
}),
});
const user = await trpc.getUser.query({ id: "123" });
// user is typed from the database query result
Our explainers on tRPC and Hono cover the trade-offs. Note the z.object call: that is Zod, a runtime validation library, and it is there for a reason covered shortly.
Type-safe database access
Typed ORMs and query builders extend the chain to the database. With Prisma:
const prisma = new PrismaClient();
const users = await prisma.user.findMany({
where: { active: true },
include: { posts: true },
});
// users is typed as (User & { posts: Post[] })[]
And with Drizzle:
const users = await db.select().from(usersTable).where(eq(usersTable.active, true));
Both derive types from your schema, so a renamed column becomes a compile error in every query that used it. For a closer look at the second approach, read about Drizzle ORM. The same idea of typed contracts reaches into AI work: Pydantic AI applies it to Python language-model apps, and our piece on JSON mode versus structured outputs covers why constraining model output to a schema matters.
The gap types cannot close: data from outside
Because types vanish at runtime, they cannot verify anything that arrives while the program is running. The classic trap:
const res = await fetch("/api/user");
const user = (await res.json()) as User; // a promise to the compiler, not a check
console.log(user.email.toLowerCase()); // crashes if the server sent no email
The as User assertion tells the compiler to trust you. If the server changes its response, nothing complains until the line runs. Data from fetch, JSON.parse, form inputs, environment variables, and third-party webhooks all need validation at the boundary. Libraries such as Zod let you write one schema that does both jobs: it checks the data at runtime and produces the TypeScript type.
The rule of thumb: inside your program, trust the types. At the edges, trust nothing, and validate. Most "but TypeScript said it was fine" bugs live in the gap between those two zones.
Common mistakes and how to avoid them
Using any to silence an error. any turns the checker off for that value and everything it touches. Use unknown and narrow it, or write the correct type. If you truly cannot, leave a comment explaining why so the next reader knows it was a decision.
Skipping strict mode. Without strictNullChecks, the compiler ignores null and undefined, which are the source of the most common runtime crashes in JavaScript. A project without strict settings gets only a fraction of the benefit.
Over-engineering types. Beginners discover conditional types and mapped types and build a puzzle nobody can read. Start with plain object types and unions. Reach for advanced features when you have a concrete duplication problem.
Muting errors with // @ts-ignore. Each one is a place where the compiler found something and you chose not to look. If you must suppress, // @ts-expect-error is safer because it complains when the error disappears, which keeps stale suppressions from piling up.
Annotating everything. Writing const count: number = 0 adds noise. Let inference work on local variables and annotate the boundaries.
Trusting casts. as does not convert or check; it overrides. Frequent casts usually mean the types upstream are wrong.
When any is a reasonable choice
There are honest uses: a migration of a large legacy codebase, a third-party library with no type definitions, or truly dynamic data you will narrow immediately. Even then, unknown is usually the better first choice because it forces the check. A small number of well-commented any values at the edges is fine. A codebase full of them has the syntax of TypeScript and the safety of JavaScript.
Limits of TypeScript
TypeScript does not make programs correct. It catches one class of mistakes, mismatched kinds of values, and says nothing about whether your logic is right. A function that adds when it should subtract type-checks perfectly. Security flaws, race conditions, and off-by-one errors pass straight through.
Its type system is also "unsound" by design in a few places, meaning there are deliberate escape hatches (any, casts, some array and function behaviors) where the compiler accepts code that could fail. The handbook's stated goal is to allow correct programs through "while still catching as many common errors as possible," which is a practical compromise, not a proof.
And there is a human cost. A confusing generic error message can eat an afternoon, and over-typed code can be harder to read than the JavaScript it replaced. The honest summary: TypeScript pays off most where code lives long, changes often, or is shared by several people, and pays off least in short, solo, disposable scripts.
What to learn, in what order
If you are learning web development from scratch, the order that tends to work is JavaScript fundamentals first, so that you understand what the types are describing, then TypeScript within a few weeks. The handbook says it bluntly: "You can't learn TypeScript without learning JavaScript." Our JavaScript fundamentals guide and the complete web development learning path lay out that sequence, and the best web development tools of 2026 covers editors and frameworks with good TypeScript support. For styling, the Tailwind CSS explainer pairs well with typed component libraries.
One more observation about AI tools: if you use AI-assisted coding, typed code gives you a faster way to check what the assistant produced, because the compiler rejects a whole category of mistakes immediately. Our explainer on vibe coding discusses where that kind of review still falls short.
Frequently asked questions
Q: Should I learn JavaScript or TypeScript first?
A: JavaScript first. TypeScript describes JavaScript, so you need to know variables, functions, async behavior, and the DOM before the annotations make sense. Move to TypeScript within a few weeks, once the basics feel comfortable.
Q: Is TypeScript slower than JavaScript at runtime?
A: No. The types are erased during compilation, so the running program is plain JavaScript. The only cost is at build time, and TypeScript 7's native compiler is reported to cut full-build times by 8x to 12x on large projects.
Q: Does TypeScript catch all bugs?
A: No. It catches mismatched types at compile time. It does not check logic, and it cannot verify data that arrives at runtime, such as an API response, unless you validate it with a tool like Zod.
Q: Is TypeScript a superset of JavaScript?
A: Yes, in syntax. The handbook says JavaScript syntax is legal TypeScript. Valid JavaScript can still produce type errors, but the compiled output behaves the same way regardless of those errors.
Q: Can I run TypeScript without compiling it?
A: Partly. Node.js can strip types and run .ts files directly in recent versions, but it performs no type checking and rejects syntax such as enums and runtime namespaces. You still need tsc or an editor to check types.
Q: Is TypeScript hard to learn?
A: The first weeks are the steepest, mostly because of error messages and unfamiliar syntax. The core you need for daily work is small: annotations, unions, narrowing, interfaces, and a basic grasp of generics.
Q: Should I use type or interface?
A: Either works for object shapes. Interfaces can be extended and merged, while type also handles unions and tuples. Pick one convention per codebase and apply it consistently.
The takeaway
TypeScript's value is not magic. It is a cheap, automatic reviewer that reads your whole program before it runs and objects when your descriptions and your code disagree. It works best when you turn strict checks on, describe boundaries carefully, narrow values with plain checks, and validate anything that arrives from outside, because annotations disappear before the code runs. It is not required for every project, but the ecosystem around it, from framework templates to a native compiler that makes type-checking fast, means reading and writing it is now an ordinary part of web development.
Sources
- TypeScript Handbook: TypeScript for JavaScript Programmers (From Scratch)
- TypeScript TSConfig reference: strict
- Vite guide: Features (TypeScript)
- Stack Overflow Developer Survey 2025: Technology
- GitHub Octoverse 2025: AI leads TypeScript to #1
- InfoQ: TypeScript 7 released
- Node.js documentation: Modules: TypeScript
Last verified: October 19, 2026
Follow new articles
Add SciHub101 to your feed reader to see new science and technology stories.
About the Author
SciHub101 is an independent science and technology publication founded and edited by Buğra Sözeri, a software engineer and app developer based in Türkiye. AI tools assist with drafting and research. Source documentation in the existing archive is uneven, and articles are being reviewed and corrected. The Editorial Team byline identifies editorial responsibility; it does not certify specialist or independent human review. Where we compare products, anything built by our own team is labelled as such — see the editorial guidelines and About page for how corrections and disclosures work.
Related Articles

Tailwind CSS Explained — Why It Dominates Web Design 2026
Tailwind CSS for beginners: why utility-first CSS won, common patterns, integration with React/Next.js, gotchas. The CSS framework everyone uses in 2026.

ORMs 2026 — Prisma vs Drizzle vs Kysely Honest Comparison
Real comparison of TypeScript ORMs in 2026 — Prisma, Drizzle, Kysely, TypeORM — for type safety, performance, edge compatibility, and migration story.

What Is HTMX? Hypermedia for Modern Web
HTMX explained: how this 14KB library lets you build dynamic web apps with HTML attributes instead of a JavaScript framework, plus how it actually works.

Bun vs Node.js vs Deno — 2026 Comparison
Bun is fastest, Node is bulletproof, Deno is the most secure. A 2026 comparison of the three major JavaScript runtimes with benchmarks and trade-offs.

Next.js vs React 2026 — Which Should You Learn First?
Next.js is a framework built on React, not a rival. What each does, Server Components, App vs Pages Router, and when to pick which, per the official docs.

Web Development Job Market 2026 — Salaries & Careers
Web dev job market 2026: BLS salary data by experience, location, and specialization, plus hiring trends, remote work shifts, and negotiation tactics.