I put off TypeScript for a long time because every tutorial I opened started with a wall of generics and utility types. It looked like a second language bolted onto the one I already knew. Then I joined a project where everything was .ts, and I had to get useful in about a week.
What I found is that you don't need most of TypeScript to be productive. You need a small core, a compiler that yells at you, and some patience for the first few days when the red squiggles feel personal. This is the order I'd learn it in again.
Start by renaming a file
Don't start with a course. Take a small JavaScript project you already understand, add TypeScript, and rename one file from .js to .ts.
npm install --save-dev typescript
npx tsc --init
Then turn on "strict": true in tsconfig.json. People sometimes say to leave strict mode off while you learn. I think that's backwards. Strict mode is where most of the teaching happens, because it forces you to deal with undefined and implicit any right away instead of discovering them later.
The errors you get from that one renamed file are a better syllabus than any table of contents. Fix them one at a time and look up each error you don't understand.
Learn the handful of types you'll use every day
Most real TypeScript code uses a short list of features over and over:
type User = {
id: number;
name: string;
email?: string; // optional
};
function greet(user: User): string {
return `Hi, ${user.name}`;
}
type Status = "idle" | "loading" | "error";
Object types, optional properties, function parameter and return types, union types, and arrays like User[]. That covers a surprising amount of what you'll write in your first month.
Also learn the difference between type and interface just well enough to stop worrying about it. For everyday object shapes, either works. Pick one for your project and move on. I lost an evening reading opinions about this and it changed nothing in my code.
Let inference do the work
A mistake I made early was annotating everything:
const count: number = 0;
const names: string[] = users.map((u: User): string => u.name);
TypeScript already knows all of that. Most of the time you only need types at the edges: function parameters, return types of exported functions, and data coming from outside (API responses, JSON.parse, form input). Inside a function, let the compiler infer. Your code ends up looking a lot like plain JavaScript, which is the point.
Hover over variables in your editor to see what TypeScript thinks they are. That habit alone taught me more than reading the handbook front to back.
Narrowing is the part that clicks late
The concept that took me longest was narrowing. You have a value that could be a few things, and you check which one it is:
function format(input: string | number) {
if (typeof input === "string") {
return input.toUpperCase(); // TS knows it's a string here
}
return input.toFixed(2); // and a number here
}
The same idea works with in, instanceof, equality checks against null, and discriminated unions where each variant has a kind field. Once narrowing makes sense, most of the "why is this possibly undefined?" errors stop being mysterious. You just check the value and the error goes away.
Things to skip for now
Generics are worth learning, but only once you've written the same function twice for two types and felt annoyed. Until then you'll mostly use generics other people wrote, like Array<T> or Promise<T>, and that's fine.
Skip conditional types, mapped types, infer, declaration merging and the type-level puzzles that go around on social media. They're fun, and library authors need them. Application code rarely does. I tried to learn mapped types in my second week and couldn't explain them a month later because I never used them.
And go easy on any. It's tempting when you're stuck, but each any switches off checking for everything it touches. If you truly don't know a type, unknown is the safer option because it makes you narrow before you use the value.
Make it stick
The hard part of learning TypeScript wasn't finding good explanations. The official TypeScript Handbook is good, Matt Pocock's free material on Total TypeScript is good, and there are plenty of short videos on narrowing or satisfies. My problem was that I'd watch one on a weekend, nod along, and then a few weeks later hit the exact error it explained and remember nothing except that I'd seen a video about it once.
That's the gap I built Recl for. You share a video, reel, podcast or article to it, it summarizes the key points, puts it under a topic like "TypeScript", and brings it back on a spaced repetition schedule so you review it before it fades. A plain notes file of "errors I fixed and why" that you reread every couple of weeks does a lot of the same job if you'd rather keep things simple. What matters is seeing the material again, ideally right before you'd have forgotten it.
A one-week plan
If you want something concrete, here's roughly what my first week looked like:
- Day one: add TypeScript to a small project, turn on strict mode, convert one file.
- Days two and three: convert a few more files, fixing errors as they come up and looking up each one.
- Day four: type an API response properly instead of using
any. - Day five: refactor something into a discriminated union and use narrowing.
- Weekend: read the handbook sections on everyday types and narrowing. They'll make far more sense now that you've hit the problems they solve.
You'll still look things up after that. I do, constantly. But you'll be writing TypeScript, and the rest you can pick up when a real problem asks for it.
I build Recl, an AI learning app that saves your videos, reels, podcasts and articles, summarizes them, sorts them into topics, and uses spaced repetition so you remember what you learned.
Top comments (0)