---
# System prepended metadata

title: TypeScript Cookbook

---

# TypeScript Cookbook

This is a random collection (in no particular order) of "Recipes" and tips that I've collected over time, about how to be more effective using TypeScript.

## 📖 Create a type that is a derived map from another type:

```typescript=
interface Foo {
  bar: string;
  blah: number;
  flip: 'flop' | null,
  yippie?: 123 | 456 | 789
}

// This is a new type based on Foo, which has every property of Foo but now each property can be a boolean in addition to whatever it could have been before
type FooBar = { [K in keyof Foo]: Foo[K] | boolean };
```

## 💡 It's often not safe to use ! (non-null assertion) in lambdas
TypeScript will complain about the possibility of null if you use an object in a lambda. In some cases, TypeScript will be wrong, but in more cases than you think, it will be right.

Consider this code snippet:

```typescript=
let el = document.getElementById('stephen');
if (!el) {
    el = document.createElement('div');

    window.requestAnimationFrame(() => {
        el!.removeAttribute('blah');
    });
}
goDoSomeWork(el);

function goDoSomeWork(myEl: HTMLElement) {
    setTimeout(() => {
        el = null;
    }, 3)
}
```

At first glance, this looks safe, and you wonder why TS insists that `el` could be `null`. After all, `el` is *definitely* created if it wasn't found, so what's the problem? It's that the function being invoked is a lambda to `requestAnimationFrame` which means it is NOT guaranteed to run immediately after line 3. Because of line 9 and that fact that your lambda is merely queued for exeution, this will, indeed, cause a runtime error.

It's worth noting that TS will complain even for synchronous execution of lambdas. For example, if you tried to set the same style properties inside a `forEach`, TS will still complain, however, in that case it would be safe. Still, I recommend using `?` in both cases. In the first case it can actually prevent a runtime error, and in the second case, you never know when someone might change your code later, making the `!` unsafe.

Here's a better option:
```typescript=
let el = document.getElementById('stephen');
if (!el) {
    el = document.createElement('div');

    window.requestAnimationFrame(() => {
        el?.removeAttribute('blah');
    });
}
goDoSomeWork(el);

function goDoSomeWork(myEl: HTMLElement) {
    setTimeout(() => {
        el = null;
    }, 3)
}
```

## 💡 Be careful with optional properties and type guards
In the following example, TypeScript complains about the last line of code: ``"Property 'canFly' does not exist on type 'never'"``

```typescript
interface Bird {
    canFly: true;
}

interface FlyingSnake extends Bird {
    isPoisonous?: boolean;
}

class Parrot implements FlyingSnake {
    canFly: true = true;
}

function isBird(parrot: Parrot): parrot is Bird {
    return !!'does not matter';
}

const p = new Parrot();
if (isBird(p)) {
    throw new Error('It is a bird');
}

console.log(p.canFly);
```typescript