# TypeScript (/docs/concepts/typescript)

了解 Better Auth 的 TypeScript 配置，包括严格模式、推断会话和用户类型、定义额外字段以及在客户端上推断额外字段。



Better Auth 被设计为类型安全的。客户端和服务器端均使用 TypeScript 构建，允许你轻松推断类型。

## TypeScript 配置 [#typescript-配置]

Better Auth 被设计为与 TypeScript 的严格模式配合使用。我们建议在你的 TypeScript 配置文件中启用严格模式：

```json title="tsconfig.json"
{
  "compilerOptions": {
    "strict": true
  }
}
```

如果你无法将 `strict` 设置为 `true`，你可以启用 `strictNullChecks`：

```json title="tsconfig.json"
{
  "compilerOptions": {
    "strictNullChecks": true,
  }
}
```

当 `strict` 设置为 `true` 时，`strictNullChecks` 也会被启用。如果你显式地将 `strictNullChecks` 设置为 `false`，可能会导致类型推断问题。

<Callout type="warn">
  如果你遇到 TypeScript 推断超出编译器可序列化的最大长度的问题，请确保你遵循上述说明，并确保 `declaration` 和 `composite` 均未启用。
</Callout>

## 类型推断 [#类型推断]

客户端 SDK 和服务器端都提供可通过 `$Infer` 属性推断的类型。插件可以扩展基础类型，如 `User` 和 `Session`，你可以使用 `$Infer` 来推断这些类型。此外，插件还可以提供额外的类型，也可以通过 `$Infer` 进行推断。

```ts title="auth-client.ts"
import { createAuthClient } from "better-auth/client"

const authClient = createAuthClient()

export type Session = typeof authClient.$Infer.Session
```

`Session` 类型包含 `session` 和 `user` 两个属性。`user` 属性表示用户对象类型，`session` 属性表示会话对象类型。

你也可以在服务器端推断类型。

```ts title="auth.ts"
import { betterAuth } from "better-auth"
import Database from "better-sqlite3"

export const auth = betterAuth({
    database: new Database("database.db")
})

type Session = typeof auth.$Infer.Session
```

## 额外字段 [#额外字段]

Better Auth 允许你向用户和会话对象添加额外字段。所有额外字段都会被正确推断，并在服务器和客户端上可用。

```ts title="auth.ts"
import { betterAuth } from "better-auth"
import Database from "better-sqlite3"

export const auth = betterAuth({
    database: new Database("database.db"),
    user: {
       additionalFields: {
          role: {
              type: "string",
              input: false
            } 
        }
    }
   
})

type Session = typeof auth.$Infer.Session
```

在上面的示例中，我们向用户对象添加了一个 `role` 字段。该字段现在可以在 `Session` 类型中使用。

### `input` 属性 [#input-属性]

若要阻止某个字段成为用户输入部分，必须显式设置 `input: false`：

```ts
additionalFields: {
    role: {
        type: "string",
        input: false
    }
}
```

当 `input` 设置为 `false` 时，该字段将被排除在用户输入之外，防止用户传入该字段的值。

默认情况下，额外字段包含在用户输入中，如果处理不当可能带来安全隐患。对于不应由用户设置的字段（如 `role`），请务必在配置中将 `input` 设置为 `false`。

### 在客户端推断额外字段 [#在客户端推断额外字段]

为了确保客户端正确推断额外字段的类型，你需要告知客户端这些字段。根据项目结构，有两种方法：

1. 对于 Monorepo 或单一项目设置

如果你的服务器和客户端代码在同一个项目中，可以使用 `inferAdditionalFields` 插件从服务器配置自动推断额外字段。

```ts title="auth-client.ts"
import { inferAdditionalFields } from "better-auth/client/plugins";
import { createAuthClient } from "better-auth/client";
import type { auth } from "@/lib/auth"; // 将 auth 实例作为类型导入

export const authClient = createAuthClient({
  plugins: [inferAdditionalFields<typeof auth>()],
});
```

2. 对于客户端和服务器分离的项目

如果客户端和服务器在不同项目中，你需要在创建认证客户端时手动指定额外字段。

```ts title="auth-client.ts"
import { createAuthClient } from "better-auth/client";
import { inferAdditionalFields } from "better-auth/client/plugins";

export const authClient = createAuthClient({
  plugins: [inferAdditionalFields({
      user: {
        role: {
          type: "string"
        }
      }
  })],
});
```

