Help Wanted: Generic types when registering a plugin
- Dominant language
- No language data
- Stars
- 68
- Forks
- 8
- Avg merge
- 11h 2m
- Merged PRs (30d)
- 2
Description
#### What are you trying to achieve, or the steps to reproduce?
I'm trying to create a plugin to `register` a new function on the Fastify instance which will hold an instance of [Prisma](https://www.prisma.io/)
```js
// plugin.ts
import { FastifyPluginAsync, FastifyPluginOptions } from "fastify";
import fp from "fastify-plugin";
declare module "fastify" {
interface FastifyInstance {
prisma; // Should be the type of the instantiated `PrismaClient`
}
}
interface PrismaPluginOptions extends FastifyPluginOptions {
client; // Should be the type of the `client` key's value passed via `options`
}
const prismaPlugin: FastifyPluginAsync = async (
fastify,
options
) => {
const PrismaClient = options.client;
if (!PrismaClient) {
throw new Error(
"`client` parameter is required. Please provide a generated PrismaClient class."
);
}
if (!fastify.prisma) {
const prisma = new PrismaClient();
fastify.decorate("prisma", prisma);
fastify.addHook("onClose", async (server) => {
await server.prisma.$disconnect();
});
}
};
export default fp(prismaPlugin, "3.x");
```
The goal is to be able to register the plugin and provide the PrismaClient `class` via a `client` key. Within the actual server's code, I'd expect `fastify.prisma` to be of the type of the instantiated class `PrismaClient`.
```js
// server.ts
import Fastify from "fastify";
import prismaPlugin from "../index";
import { PrismaClient } from "@prisma/client";
const fastify = Fastify();
fastify.register(prismaPlugin, {
client: PrismaClient,
});
fastify.get("/", async (request, reply) => {
const data = fastify.prisma // Should be of the type `PrismaClient`
return { count: 1 };
});
fastify.listen({ port: 3000 });
```
#### What was the result you received?
I'm having trouble figuring out how to use generic types to ensure `fastify.prisma` is the type of the provided class.
#### What did you expect?
After registering the plugin and providing the class via the `client` option, I'd want the `data` variable here to be of the type `PrismaClient`:
```js
fastify.get("/", async (request, reply) => {
const data = fastify.prisma
// ...
});
```
The result should be the same as if I had done:
```js
declare module "fastify" {
interface FastifyInstance {
prisma: PrismaClient;
}
}
fastify.decorate("prisma", new PrismaClient());
fastify.get("/", async (request, reply) => {
const data = fastify.prisma; // type: PrismaClient
return { count: 1 };
});
```
#### Context
* *node version*: v16.15.1
* *fastify version*: any
* *os*: Mac
* *any other relevant information*:
Contributor guide
Assessment
This issue has not been assessed yet.