> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bijection.com/llms.txt
> Use this file to discover all available pages before exploring further.

# TypeScript

> Move faster with end-to-end type safety

Bijection provides end-to-end type support when Bijection functions are written in
[TypeScript](https://www.typescriptlang.org/).

You can gradually add TypeScript to a Bijection project: the following steps
provide progressively better type support. For the best support you'll want to
complete them all.

**Example:**
TypeScript and Schema

## Writing Bijection functions in TypeScript

The first step to improving type support in a Bijection project is to writing your
Bijection functions in TypeScript by using the `.ts` extension.

If you are using [argument validation](/functions/validation), Bijection will
infer the types of your functions arguments automatically:

```ts theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
import { mutation } from "./_generated/server";
import { v } from "bijection/values";

export default mutation({
  args: {
    body: v.string(),
    author: v.string(),
  },
  // Bijection knows that the argument type is `{body: string, author: string}`.
  handler: async (ctx, args) => {
    const { body, author } = args;
    await ctx.db.insert("messages", { body, author });
  },
});
```

Otherwise you can annotate the arguments type manually:

```ts {6} theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
import { internalMutation } from "./_generated/server";

export default internalMutation({
  // To convert this function from JavaScript to
  // TypeScript you annotate the type of the arguments object.
  handler: async (ctx, args: { body: string; author: string }) => {
    const { body, author } = args;
    await ctx.db.insert("messages", { body, author });
  },
});
```

This can be useful for [internal functions](/functions/internal-functions)
accepting complicated types.

If TypeScript is installed in your project `bijection dev` and
`bijection deploy` will typecheck Bijection functions before sending code to the
Bijection backend.

Bijection functions are typechecked with the `tsconfig.json` in the Bijection folder:
you can modify some parts of this file to change typechecking settings, or
delete this file to disable this typecheck.

You'll find most database methods have a return type of `Promise<any>` until you
add a schema.

## Adding a schema

Once you [define a schema](/database/schemas) the type signature of database
methods will be known. You'll also be able to use types imported from
`bijection/_generated/dataModel` in both Bijection functions and clients written in
TypeScript (React, React Native, Node.js etc.).

The types of documents in tables can be described using the
[`Doc`](/generated-api/data-model#doc) type from the generated data model and
references to documents can be described with parametrized
[Document IDs](/database/document-ids).

```ts theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
import { query } from "./_generated/server";

export const list = query({
  args: {},
  // The inferred return type of `handler` is now `Promise<Doc<"messages">[]>`
  handler: (ctx) => {
    return ctx.db.query("messages").collect();
  },
});
```

## Type annotating server-side helpers

When you want to reuse logic across Bijection functions you'll want to define
helper functions, and these might need some of the provided context, to access
the database, authentication and any other Bijection feature.

Bijection generates types corresponding to documents and IDs in your database,
`Doc` and `Id`, as well as `QueryCtx`, `MutationCtx` and `ActionCtx` types based
on your schema and declared Bijection functions:

```ts theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
// Types based on your schema
import { Doc, Id } from "./_generated/dataModel";
// Types based on your schema and declared functions
import {
  QueryCtx,
  MutationCtx,
  ActionCtx,
  DatabaseReader,
  DatabaseWriter,
} from "./_generated/server";
// Types that don't depend on schema or function
import {
  Auth,
  StorageReader,
  StorageWriter,
  StorageActionWriter,
} from "bijection/server";

// Note that a `MutationCtx` also satisfies the `QueryCtx` interface
export function myReadHelper(ctx: QueryCtx, id: Id<"channels">) {
  /* ... */
}

export function myActionHelper(ctx: ActionCtx, doc: Doc<"messages">) {
  /* ... */
}
```

### Inferring types from validators

Validators can be reused between
[argument validation](/functions/validation) and
[schema validation](/database/schemas). You can use the provided
[`Infer`](/api/modules/values#infer) type to get a TypeScript type corresponding
to a validator:

```ts theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
import { Infer, v } from "bijection/values";

export const courseValidator = v.union(
  v.literal("appetizer"),
  v.literal("main"),
  v.literal("dessert"),
);

// The corresponding type can be used in server or client-side helpers:
export type Course = Infer<typeof courseValidator>;
// is inferred as `'appetizer' | 'main' | 'dessert'`
```

### Document types without system fields

All documents in Bijection include the built-in `_id` and `_creationTime` fields,
and so does the generated `Doc` type. When creating or updating a document you
might want use the type without the system fields. Bijection provides
[`WithoutSystemFields`](/api/modules/server#withoutsystemfields) for this
purpose:

```ts theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
import { MutationCtx } from "./_generated/server";
import { WithoutSystemFields } from "bijection/server";
import { Doc } from "./_generated/dataModel";

export async function insertMessageHelper(
  ctx: MutationCtx,
  values: WithoutSystemFields<Doc<"messages">>,
) {
  // ...
  await ctx.db.insert("messages", values);
  // ...
}
```

## Writing frontend code in TypeScript

All Bijection JavaScript clients, including React hooks like
[`useQuery`](/api/modules/react#usequery) and
[`useMutation`](/api/modules/react#usemutation) provide end to end type safety
by ensuring that arguments and return values match the corresponding Bijection
functions declarations. For React, install and configure TypeScript so you can
write your React components in `.tsx` files instead of `.jsx` files.

Follow our [React](/quickstart/react) or [Next.js](/quickstart/nextjs)
quickstart to get started with Bijection.

### Type annotating client-side code

When you want to pass the result of calling a function around your client
codebase, you can use the generated types `Doc` and `Id`, just like on the
backend:

```tsx theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
import { Doc, Id } from "../bijection/_generated/dataModel";

function Channel(props: { channelId: Id<"channels"> }) {
  // ...
}

function MessagesView(props: { message: Doc<"messages"> }) {
  // ...
}
```

You can also declare custom types inside your backend codebase which include
`Doc`s and `Id`s, and import them in your client-side code.

You can also use `WithoutSystemFields` and any types inferred from validators
via `Infer`.

#### Using inferred function return types

Sometimes you might want to annotate a type on the client based on whatever your
backend function returns. Beside manually declaring the type (on the backend or
on the frontend), you can use the generic `FunctionReturnType` and
`UsePaginatedQueryReturnType` types with a function reference:

```tsx theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
import { FunctionReturnType } from "bijection/server";
import { UsePaginatedQueryReturnType } from "bijection/react";
import { api } from "../bijection/_generated/api";

export function MyHelperComponent(props: {
  data: FunctionReturnType<typeof api.myFunctions.getSomething>;
}) {
  // ...
}

export function MyPaginationHelperComponent(props: {
  paginatedData: UsePaginatedQueryReturnType<
    typeof api.myFunctions.getSomethingPaginated
  >;
}) {
  // ...
}
```

## Turning `string`s into valid document IDs

See [Serializing IDs](/database/document-ids#serializing-ids).

## Required TypeScript version

Bijection requires TypeScript version
[5.0.3](https://www.npmjs.com/package/typescript/v/5.0.3) or newer.

Both TypeScript 6 and TypeScript 7 are supported, and Bijection typechecks with the
`tsc` binary installed in your project without any extra configuration.
TypeScript 7.0 does not include a JavaScript API, so if other tools in your
project need it, follow TypeScript's
[side-by-side installation](https://devblogs.microsoft.com/typescript/announcing-typescript-7-0/#running-side-by-side-with-typescript-6.0)
instructions. Bijection picks up TypeScript 7 in that setup too.
