fastify / fastify/help

Help Wanted: Generic types when registering a plugin

Open
#743 1 comment 0 reactions 0 assignees View on GitHub
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.