# 类型自动推导

URL: https://caijiao.org/fastify/typescript/inference
Source: docs/fastify/typescript/inference.md
Description: 介绍 Fastify 中如何使用 TypeScript 进行类型自动推导，使得开发者能够享受更强的类型安全和自动补全功能。

TypeScript 提供了强大的类型推导功能，可以自动推导出变量、函数返回值、参数等的类型。这使得开发者能够在编写代码时获得更好的类型安全和自动补全，减少出错的几率。在 Fastify 中，利用 TypeScript 的类型推导功能，能够显著提高代码的开发效率和可维护性。

## 1. 基础类型推导

TypeScript 可以根据赋值或函数返回值自动推导类型。在 [Fastify](/fastify/) 项目中，TypeScript 会自动推导请求和响应对象的类型，尤其是在使用 `FastifyRequest` 和 `FastifyReply` 类型时，推导会非常有用。

### 例子：请求体类型推导

假设你有一个 POST 请求，接收一个 JSON 对象作为请求体。TypeScript 可以根据你传递的数据类型自动推导出请求体的类型。

```typescript
import fastify from 'fastify';

const app = fastify();

interface Greeting {
  name: string;
  age: number;
}

app.post('/greet', async (request, reply) => {
  const { name, age }: Greeting = request.body; // 自动推导 request.body 类型为 Greeting
  return { greeting: `Hello, ${name}, you are ${age} years old` };
});

app.listen(3000, (err, address) => {
  if (err) {
    app.log.error(err);
    process.exit(1);
  }
  app.log.info(`Server listening at ${address}`);
});
```

在这个例子中，`request.body` 会自动推导为 `Greeting` 类型，TypeScript 会确保请求体符合 `name` 和 `age` 的要求。

## 2. 路由参数与查询字符串自动推导

Fastify 允许你定义路由参数和查询字符串的类型，TypeScript 会自动推导这些参数的类型。

### 例子：路由参数推导

```typescript
app.get('/greet/:name', async (request, reply) => {
  const { name } = request.params; // 自动推导 request.params 类型
  return { greeting: `Hello, ${name}` };
});
```

在这个例子中，`request.params` 会自动推导为 `{ name: string }` 类型。

### 例子：查询字符串推导

```typescript
app.get('/search', async (request, reply) => {
  const { query } = request;
  const { term, limit } = query; // 自动推导 query.term 和 query.limit 的类型
  return { searchResults: `Searching for ${term}, limit: ${limit}` };
});
```

这里，`request.query` 会自动推导为 `Querystring` 类型，`term` 会被推导为 `string`，`limit` 会被推导为 `string` 或 `number`，具体取决于查询字符串的内容。

## 3. Fastify 类型定义与自动推导

Fastify 提供了内置的类型定义，帮助自动推导请求、响应、查询字符串、路由参数等的类型。以下是一些 Fastify 相关的类型推导示例。

### 例子：请求体类型定义

在 Fastify 中，你可以通过 `FastifyRequest` 类型来推导请求体的类型，确保请求体的数据结构正确。

```typescript
import fastify from 'fastify';

const app = fastify();

interface MySchema {
  name: string;
}

app.post('/greet', async (request, reply) => {
  const { name }: MySchema = request.body; // 自动推导为 MySchema 类型
  return { greeting: `Hello, ${name}` };
});
```

在此，`request.body` 被自动推导为 `MySchema` 类型。

### 例子：响应类型推导

Fastify 还可以推导路由返回值的类型，帮助自动补全响应对象的数据类型。

```typescript
app.get('/greet/:name', async (request, reply) => {
  const { name } = request.params;
  reply.send({ greeting: `Hello, ${name}` }); // 自动推导返回值类型为 { greeting: string }
});
```

在这个例子中，`reply.send()` 会推导返回值的类型为 `{ greeting: string }`，确保返回的数据符合预期。

## 4. 使用类型声明增强自动推导

在实际开发中，可以利用 TypeScript 的类型声明增强功能，为 Fastify 路由和插件添加更多自定义类型，进一步优化类型推导。

### 例子：增强路由类型

你可以通过定义 `RouteHandlerMethod` 来增强某个路由的类型，确保在使用时能够自动推导正确的请求、响应和路由参数类型。

```typescript
import { FastifyInstance, RouteHandlerMethod } from 'fastify';

const handler: RouteHandlerMethod = async (request, reply) => {
  const { name } = request.params;
  return { greeting: `Hello, ${name}` };
};

const app: FastifyInstance = fastify();

app.get('/greet/:name', handler);
```

在这个例子中，Fastify 会自动推导出 `request.params` 为 `{ name: string }`，并根据路由返回的内容推导出响应类型。

## 5. 总结

类型自动推导是 TypeScript 提供的强大功能，它能够在开发过程中提供智能的类型推导和自动补全，帮助开发者减少类型错误，提高代码的可靠性。在 Fastify 中，借助 TypeScript 的类型推导，我们可以轻松地为请求体、路由参数、查询字符串等定义类型，使得开发过程更加高效和安全。
