Skip to content

feat: decorate fastify instance with addittional properties#5093

Closed
DemonHa wants to merge 8 commits intofastify:mainfrom
DemonHa:type-safe-plugin-definitions
Closed

feat: decorate fastify instance with addittional properties#5093
DemonHa wants to merge 8 commits intofastify:mainfrom
DemonHa:type-safe-plugin-definitions

Conversation

@DemonHa
Copy link
Copy Markdown
Contributor

@DemonHa DemonHa commented Oct 13, 2023

Proposal regarding to #5061

We are decorating the FastifyInstance to take into account decorators so it can work together with fastifyPlugin in order to have to end to end type safe apis.

This PR is a draft so any suggestion will be highly appreciated.

Checklist

@Uzlopak
Copy link
Copy Markdown
Contributor

Uzlopak commented Oct 13, 2023

It feels kind of wrong to change the FastifyInstance to a type. Doesnt this result in potential issues because you maybe cant extend from a type?

Also i think AppInstance or app is a term of expressjs. A AppInstance or App in fastify is the FastifyInstance.

@DemonHa
Copy link
Copy Markdown
Contributor Author

DemonHa commented Oct 13, 2023

@Uzlopak Actually you can extend a type the same way you do with an interface

@DemonHa
Copy link
Copy Markdown
Contributor Author

DemonHa commented Oct 13, 2023

@Uzlopak If you are talking about declaration merging then you are correct, but this is the thing we are trying to avoid

@DemonHa DemonHa marked this pull request as draft November 4, 2023 13:05
@mcollina mcollina self-requested a review May 1, 2024 14:58
@mcollina
Copy link
Copy Markdown
Member

mcollina commented May 2, 2024

@DemonHa what can we do to help you ship this?

@DemonHa
Copy link
Copy Markdown
Contributor Author

DemonHa commented May 2, 2024

@DemonHa what can we do to help you ship this?

Getting feedback as early as possible would be a great help.

@DemonHa
Copy link
Copy Markdown
Contributor Author

DemonHa commented May 4, 2024

Was thinking how would it work with a plugin like autoload or even when defining routes on a separate function.

We would probably need a generic to tell us which plugins have been registered. Wdyt @mcollina ?

@Eomm Eomm added the typescript TypeScript related label May 5, 2024
@nemanja-tosic nemanja-tosic mentioned this pull request Sep 8, 2024
4 tasks
Copy link
Copy Markdown
Contributor

@rozzilla rozzilla left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good approach overall! We should just avoid breaking changes 😉

// Used to type plugins written in javascript
export type GetPluginTypes<Decorators extends FastifyPluginDecorators = { decorators: {}, dependencies: [] }> = FastifyPluginCallback<{}, RawServerBase, FastifyTypeProviderDefault, FastifyBaseLogger, Decorators["decorators"] & ExtractSixGeneric<ExtractFirstFunctionParameter<Decorators["dependencies"][number] extends undefined ? {} : Decorators["dependencies"][number]>>>;

// Testing types
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typescript tests should live in test/types folder 😉

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually GetPluginTypes should not be living on the test folder at all, I just put it there for demo purposes. I think I should move it on the type definitions, since it will be exported and used by the libraries written in javascript (no library should be written in javascript IMO) or they can still use the declaration merging we currently have

RawServer extends RawServerBase = RawServerDefault,
TypeProvider extends FastifyTypeProvider = FastifyTypeProviderDefault,
Logger extends FastifyBaseLogger = FastifyBaseLogger,
Fn extends FastifyPluginCallback<Options, RawServer, TypeProvider, Logger, Decorators["decorators"]> | FastifyPluginAsync<Options, RawServer, TypeProvider, Logger, Decorators["decorators"]> = FastifyPluginCallback<Options, RawServer, TypeProvider, Logger, Decorators["decorators"]>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit (formatting)

Suggested change
Fn extends FastifyPluginCallback<Options, RawServer, TypeProvider, Logger, Decorators["decorators"]> | FastifyPluginAsync<Options, RawServer, TypeProvider, Logger, Decorators["decorators"]> = FastifyPluginCallback<Options, RawServer, TypeProvider, Logger, Decorators["decorators"]>
Fn extends FastifyPluginCallback<Options, RawServer, TypeProvider, Logger, Decorators["decorators"]> | FastifyPluginAsync<Options, RawServer, TypeProvider, Logger, Decorators["decorators"]> = FastifyPluginCallback<Options, RawServer, TypeProvider, Logger, Decorators["decorators"]>

): Fn;

// Used to type plugins written in javascript
export type GetPluginTypes<Decorators extends FastifyPluginDecorators = { decorators: {}, dependencies: [] }> = FastifyPluginCallback<{}, RawServerBase, FastifyTypeProviderDefault, FastifyBaseLogger, Decorators["decorators"] & ExtractSixGeneric<ExtractFirstFunctionParameter<Decorators["dependencies"][number] extends undefined ? {} : Decorators["dependencies"][number]>>>;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit (formatting)

Suggested change
export type GetPluginTypes<Decorators extends FastifyPluginDecorators = { decorators: {}, dependencies: [] }> = FastifyPluginCallback<{}, RawServerBase, FastifyTypeProviderDefault, FastifyBaseLogger, Decorators["decorators"] & ExtractSixGeneric<ExtractFirstFunctionParameter<Decorators["dependencies"][number] extends undefined ? {} : Decorators["dependencies"][number]>>>;
export type GetPluginTypes<Decorators extends FastifyPluginDecorators = { decorators: {}, dependencies: [] }> = FastifyPluginCallback<{}, RawServerBase, FastifyTypeProviderDefault, FastifyBaseLogger, Decorators["decorators"] & ExtractSixGeneric<ExtractFirstFunctionParameter<Decorators["dependencies"][number] extends undefined ? {} : Decorators["dependencies"][number]>>>;

@DemonHa
Copy link
Copy Markdown
Contributor Author

DemonHa commented Dec 26, 2024

Hi guys!

I have been away for quite some times since a lot of things have been going on lately.
Anyways, I found a way to keep everything as an interface so we don't introduce breaking changes. That means that people can still use declaration merging. Let me know what you guys think.

@mcollina @Uzlopak @rozzilla

@rozzilla
Copy link
Copy Markdown
Contributor

rozzilla commented Dec 26, 2024

I found a way to keep everything as an interface so we don't introduce breaking changes. That means that people can still use declaration merging. Let me know what you guys think.

I love that approach! We keep compatibility with old code while allowing new types to be introduced. Since declaration merging will still be allowed, we will probably have to mark it as deprecated. Anyway, one thing at the time. I think we should proceed that way you're suggesting 😀

Copy link
Copy Markdown
Contributor

@rozzilla rozzilla left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to fix conflicts, but now this change LGTM!

@DemonHa
Copy link
Copy Markdown
Contributor Author

DemonHa commented Dec 26, 2024

We need to fix conflicts, but now this change LGTM!

Yes, there might be quite some conflicts since this is a really old PR. I'll try to fix them today.

Copy link
Copy Markdown
Member

@gurgunday gurgunday left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I thought about this again and it is looking pretty good to me now!

@mcollina
Copy link
Copy Markdown
Member

@DemonHa what is missing?

@DemonHa
Copy link
Copy Markdown
Contributor Author

DemonHa commented Jan 15, 2025

@DemonHa what is missing?

I am creating the PR on the other projects as well and I am also going to create a little test application

import fastify, { FastifyBaseLogger, FastifyPluginAsync, FastifyPluginCallback, FastifyPluginOptions, FastifyTypeProvider, FastifyTypeProviderDefault, RawServerBase, RawServerDefault } from '../fastify'
import { FastifyDecorators, FastifyInstance } from '../types/instance'

type ExtractSixGeneric<T> = T extends FastifyInstance<any, any, any, any, any, infer U> ? U : void
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use other types and avoid any's?

@Eomm
Copy link
Copy Markdown
Member

Eomm commented Jan 17, 2026

Closing as too old

@Eomm Eomm closed this Jan 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

typescript TypeScript related

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants