NodeJS 如何将模式类型传播到fastify上的不同文件?

vsikbqxv  于 2023-06-22  发布在  Node.js
关注(0)|答案(2)|浏览(119)

我正在尝试使用Typescript的Fastify,我希望能够分离关注点。具体地说,我想将模式与控制器和路由器分开。但是,我无法轻松地传递模式类型。
我的服务器创建如下:

import Fastify from 'fastify';
import { JsonSchemaToTsProvider } from '@fastify/type-provider-json-schema-to-ts';
import balanceRoute from './features/balance/route';

const createServer = () => {
  const server = Fastify({ logger: true }).withTypeProvider<JsonSchemaToTsProvider>();

  server.get('/healthz', async (request, reply) => {
    return reply.code(200).send({
      data: {
        status: 'OK'
      }
    });
  })

  server.register(balanceRoute, { prefix: '/balance' });

  return server;
}

我的路线是:

const route = async (server: FastifyTyped) => {
  server.get(
    '/:address',
    {
      schema: GetBalanceSchema
    },
    getBalanceController
  );
};

我的控制器是:

export const getBalanceController = async (req: FastifyRequest, res: FastifyReply) => {
  console.log('Within get balance handler');
  const address = req.params.address; // PROBLEM IS HERE
  const currentBalance = await getBalance('', '');
  res.send({ hello: 'hello' });
};

我的schema如下:

import { FastifySchema } from 'fastify';

export const GetBalanceSchema: FastifySchema  = {
  params: {
    address: { type: 'string' }
  },
  querystring: {
    chainID: { type: 'string' }
  },
  response: {
    200: {
      type: 'object',
      properties: {
        data: {
          type: 'string'
        }
      }
    }
  }
} as const;

在控制器代码中,我无法让Typescript推断req.params有一个地址字段。此外,如果我在路线内移动控制器,它也没有帮助。
有什么办法能让这一切变得简单吗?
提前感谢并问候

uidvcgyl

uidvcgyl1#

这是因为您已经为模式提供了一个显式的类型注解FastifySchema,它覆盖了as const。您可以尝试删除显式类型注解:

export const GetBalanceSchema = {
...
} as const;

或者不使用as const

export const GetBalanceSchema: FastifySchema = {
...
};

甚至可以使用一个实用函数来强制类型,同时保留对象的原始结构:

function schema<S extends FastifySchema>(schema: S): S { return schema; }

export const GetBalanceSchema = schema({
...
});

但是在TypeScript 4.9中,我们有一个新的satisfies运算符,我们可以这样使用:

export const GetBalanceSchema = {
...
} satisfies FastifySchema;
lc8prwob

lc8prwob2#

在控制器文件中尝试以下操作:

export const getBalanceController = async (req: FastifyRequest<
    RouteGenericInterface,
    RawServerDefault,
    IncomingMessage,
    typeof GetBalanceSchema,
    JsonSchemaToTsProvider
  >, res: FastifyReply) => {
  console.log('Within get balance handler');
  const address = req.params.address; // PROBLEM IS HERE
  const currentBalance = await getBalance('', '');
  res.send({ hello: 'hello' });
};

并删除模式文件中的: FastifySchema类型:

export const GetBalanceSchema  = {
  params: {
    address: { type: 'string' }
  },
  querystring: {
    chainID: { type: 'string' }
  },
  response: {
    200: {
      type: 'object',
      properties: {
        data: {
          type: 'string'
        }
      }
    }
  }
} as const;

相关问题