# Static Analysis

A core design consideration in Mountaineer is allowing for full _static analysis_ of your webapps. This term just means that we can verify your code from its text alone without having to run it all. As your webapp grows in scope this becomes increasingly valuable, as it allows you to catch errors early before they become runtime issues. And the more complicated your logic becomes, the more switch conditions and edge cases you're necessarily going to have. Manually testing all that is... not going to be fun.

Since static analysis is a personal choice, we don't yet bundle a type checker within Mountaineer. This page covers some basic suggestions for adding it to your project.

<Note>
    Adding a type checker to your project might seem like overkill while the scope is still small. But we find that adding it to CI early helps prevent future headaches by taking small steps to correctly annotate your function signatures, resolve ambiguities, and catch bugs while you still have the context of implementation.
</Note>

## Python

We currently recommend [`ty`](https://docs.astral.sh/ty/), Astral's Python type checker. It's fast, integrates cleanly with `uv`, and works well in CI once your project paths are scoped in `pyproject.toml`.

```bash
uv add --dev ty
```

Then add a basic configuration to your `pyproject.toml`:

```toml
[tool.ty.src]
include = ["my_app"]
```

Then, to run against your project:

```bash
uv run ty check
```

## Typescript

Typescript's main goal as a language extension to Javascript is to provide typechecking and static analysis. These features are built into the default compiler `tsc`. As such, most frontend issues in your Mountaineer project are typically caught when we compile your typescript code with `uv run build` or progressively with `runserver` or `watch`. However there are some cases where you don't want to perform a full build, like in CI where you just want to validate the current state of your project.

```bash
npm install typescript --save-dev
```

The `tsconfig.json` specifies the level of strictness you want to enforce. These options set to the strictest level will catch the most errors:

```json title="views/tsconfig.json"
{
  "compilerOptions": {
    "strict": true,
    "noImplicitAny": true,
    "strictNullChecks": true,
    "strictFunctionTypes": true,
    "strictBindCallApply": true,
    "strictPropertyInitialization": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true
  }
}
```

| Parameter                    | Description                                                                                                                               |
|------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------|
| strict                       | Enables all strict type-checking options. Setting this to true is the easiest way to ensure you're using TypeScript's strictest settings. |
| noImplicitAny                | Raises error on expressions and declarations with an implied any type.                                                                    |
| strictNullChecks             | When enabled, null and undefined are not in the domain of every type.                                                                     |
| strictFunctionTypes          | Ensures functions' parameters are correctly typed.                                                                                        |
| strictBindCallApply          | Enforce stricter checking of the bind, call, and apply methods on functions.                                                              |
| strictPropertyInitialization | Ensures class properties are initialized in the constructor.                                                                              |
| noImplicitReturns            | Report error when not all code paths in function return a value.                                                                          |
| noFallthroughCasesInSwitch   | Prevent fall-through cases in switch statements.                                                                                          |

Then, to run against your project:

```json title="views/package.json"
{
  "scripts": {
    "typecheck": "tsc --noEmit"
  }
}
```

```bash
npm run typecheck
```
