Skip to main content

· 20 min read

TypeScript's type narrowing is a powerful feature of TypeScript's type system that lets it infer more specific types for values in areas of code. For example, TypeScript would understand that inside the following if statement, the fruit variable has to be the literal value "apple":

ts
const fruit = Math.random() > 0.5 ? "apple" : undefined;
 
fruit;
const fruit: "apple" | undefined
 
if (fruit) {
fruit;
const fruit: "apple"
}
ts
const fruit = Math.random() > 0.5 ? "apple" : undefined;
 
fruit;
const fruit: "apple" | undefined
 
if (fruit) {
fruit;
const fruit: "apple"
}

But, TypeScript's type system isn't perfect. There are some cases where TypeScript can't narrow types exactly the way you might want.

Take a look at this code snippet, where counts.apple is inferred to be type number:

ts
const counts = {
apple: 1,
};
 
counts.apple;
(property) apple: number
ts
const counts = {
apple: 1,
};
 
counts.apple;
(property) apple: number

While counts is type { apple: number }, shouldn't TypeScript know that the immediately available value of counts.apple is specifically the literal type 1 and not the general primitive type number? Can't TypeScript tell we haven't changed the value yet?

It could, but it won't. And for very good reason.

· 15 min read

TypeScript's type system is Turing Complete: meaning it has conditional branching (conditional types) and works with an arbitrary huge amount of memory. As a result, you can use the type system as its own programming language complete with variables, functions, and recursion. Developers have pushed the bounds of type operations possible in the type system to write some pretty incredible things!

This blog post is a starting list of nifty things TypeScript developers have pushed the type system to be able to do. They range from binary arithmetic and rudimentary virtual machines to maze solvers and full programming languages.

✋ This Is Not Normal

Most applications try to get away with as few extreme type operations as possible. Complex logic in the type system gets unreadable and hard to debug pretty quickly. The Learning TypeScript book advises:

If you do find a need to use type operations, please—for the sake of any developer who has to read your code, including a future you—try to keep them to a minimum if possible. Use readable names that help readers understand the code as they read it. Leave descriptive comments for anything you think future readers might struggle with.

Please don't look at the following projects list and think you need to understand them to use TypeScript. These projects are ridiculous. They're the equivalent of code golf: a fun activity for a select few, but not useful for most day-to-day work.

· 5 min read

Most popular programming languages use the void keyword to indicate that a function cannot return a value. Learning TypeScript describes TypeScript's void keyword as indicating that the returned value from a function will be ignored. Those two definitions are not always the same! TypeScript's void comes with an initially surprising behavior: a function type with a non-void return is considered assignable to a function type with a void return.

ts
let returnsVoid: () => void;
 
returnsVoid = () => "this is fine";
ts
let returnsVoid: () => void;
 
returnsVoid = () => "this is fine";

Why is that?

· 20 min read

Finding the right names and values for small code snippets is a surprisingly challenging task. Sample content like foo bar and lorem ipsum gets boring quickly -- and can be confusing to readers who aren't yet familiar with them. It's better to have self-contained code snippets that can be clearly understood without any external context.

Crafting appropriate themed content that fits cleanly with the theory being demonstrated is fraught with danger. Code snippets shouldn't contain an egregious quantity of tangentially-related setup code just to justify their theme. Themes also shouldn't be unnecessarily flashy to the point of distracting from the important conceptual explanations.

Many authors opt to stick with a small set of themes they know to be flexible and work well. I personally go with names of fruit, such as counting amounts of them. While sticking with the same theme repeatedly is reliable, it can get boring for the reader fast.

That's why, at risk of distracting ever so slightly from code content, most chapters in Learning TypeScript use an overarching theme for most or all of its code snippets. Most of the themes are fairly straightforward, such as historical authors or inventors. Others are a little more subtle and act more like easter eggs.