# TypeScript

We're using TypeScript in parts of the codebase. The intention for it is
to be a net developer productivity win, but there is bound to be a price
to it in the beginning, in learning how to solve type errors.\
In many cases they are useful pointers to errors that could happen at
runtime. In other cases they are circumstantial to the tools we are using.
In both cases you should not feel blocked by it from writing code you trust.
Fortunately TypeScript offers escape-hatches through which you can tell it
to back off.

## Escape Hatches

These allow you to tell TypeScript to be more accepting. They are generally
considered code smells and should ultimately not be needed. But pragmatically
they are better than being told by a robot that it will not run your code.\
Also a 50% type-checked codebase is better than a 0% type-checked codebase,
which is basically what most dynamically typed codebases look like. So do feel
free to rely on these to be productive!\
Also tag Gregor (and whoever wants to take on the type-fight) in those PRs
so that they can slowly work on reducing untyped code.

### `any`

When a type does not match what type expects and you do not see a good reason
for it feel free to use `any`. You can use it as a type declaration anywhere
where types can be used, e.g.:

```typescript
const n: any = 23;
function f(param: any): any {}
const s: string = 23 as any;
```

They can even be used to "trick" the type checker into believing untrue things:

```typescript
const n1: number = "text"; // Error!
const n2: number = "text" as number; // Error!
const n3: number = ("text" as any) as number; // Works!
```

Considering whether this is generally a good idea is left as an exercise to the
reader.

### `// @ts-nocheck`

When you're starting to notice that a file is becoming cluttered with type coercions
and you fighting TypeScript, you can use `// @ts-nocheck` at the beginning of the file
to tell TypeScript to back off completely. The file then effectively becomes a JS file,
though you can still do use all the TypeScript syntax.

## Common Pitfalls

### `import` is throwing `Cannot find module 'x'` despite it being installed

What TS means to say is that it is not finding types for it. For some dependecies
this can be solved by running `yarn add @types/x` (`x` being the dependecy's name).
Some dependencies might not have type declarations though, in which case you can
either [write your own](https://www.typescriptlang.org/docs/handbook/modules.html#ambient-modules)
(if you feel excited about types) or use `require` instead, which types your
dependency as `any`, thereby not giving you any compile-time guarantees.

### `'x' has no default export`

The way default exports used to work in JS does not play well with the
""new ES6"" syntax. For those dependencies you simply have to change
`import x from 'x'` to `import * as x from 'x'`.
