> Full SurrealDB documentation index: https://surrealdb.com/docs/llms.txt

# Type inference

Extract TypeScript types from Surqlize tables, edges, field types, and queries with t.infer and the type property, get the input type of a create with CreateInput, and type helpers that accept any table with TableSchema and Orm.

Surqlize derives every type from your schema, without a code generation step. When you need a named type, for a function signature or a shared interface, you extract it from the schema or from a query.

The examples below use this setup. The ORM is not connected, because the examples only read types.

```ts title="Setup for the examples"
import { Surreal } from "surrealdb";
import { orm, table, t } from "surqlize";

const user = table("user", { name: t.string(), age: t.number() });
const db = orm(new Surreal(), user);
```

## Types from queries

`t.infer<>` gives the result type of a query.

```ts title="The result type of a query"
import { t } from "surqlize";

const query = db.select("user").return((user) => ({
    name: user.name,
    age: user.age,
}));

type QueryResult = t.infer<typeof query>;
// QueryResult: { name: string; age: number }[]
```

The type follows the query. `.only()` gives a single object instead of an array, `.return()` changes the shape, and `.fetch()` replaces record links with the records they point to.

## Types from tables and edges

A table or edge has a `type` property that holds the type of a stored record. Read it with `typeof`.

```ts title="The type of a stored record"
import { table, t } from "surqlize";

const account = table("account", {
    name: t.string(),
    age: t.number(),
});

type Account = (typeof account)["type"];
// Account: { id: RecordId<"account">; name: string; age: number }
```

For a table with computed fields, the type includes them. For a table [linked to a class](/docs/libraries/surqlize-typescript/schema.md#linking-a-class-to-a-table), it is the declared fields combined with the instance type of the class.

## Types from field types

`t.infer<>` also works on a single field type.

```ts title="The type of a field"
const email = t.string();

type Email = t.infer<typeof email>;
// Email: string
```

## The input of a create

`CreateInput<>` is the type that `.content()` accepts on `create`. It takes the schema of a table. Fields that have a `.default()` and fields of type `t.option()` are optional. Computed fields and `id` are left out.

```ts title="The input of a create"
import { type CreateInput, t, table } from "surqlize";

const profile = table("profile", {
    name: t.string(),
    isVerified: t.bool().default(false),
    nickname: t.option(t.string()),
});

type NewProfile = CreateInput<(typeof profile)["schema"]>;
// NewProfile: {
//     name: string;
//     isVerified?: boolean | undefined;
//     nickname?: string | undefined;
// }
```

The same type is what [`safeParse()` and `parse()`](/docs/libraries/surqlize-typescript/validation.md#validating-data-yourself) return in their default `"create"` mode.

## Helpers that accept any table

Every table, whether or not it is linked to a class, is assignable to the bare `TableSchema` type, so a helper that accepts any table can take it as a parameter.

```ts title="Accept any table"
import type { TableSchema } from "surqlize";

function tableName(schema: TableSchema) {
    return schema.tb;
}

tableName(user);
```

The ORM has a type too. `Orm<[typeof post]>` is the type to give the `db` parameter of a [computed field](/docs/libraries/surqlize-typescript/schema.md#computed-fields) expression, with the tuple listing the tables that the expression queries.

## Next steps

- [Schema](/docs/libraries/surqlize-typescript/schema.md) - Define the tables the types come from.

- [Runtime validation](/docs/libraries/surqlize-typescript/validation.md) - Check at runtime that data has the type you expect.
