Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Typed decorators #2981

Merged
merged 9 commits into from Apr 22, 2021
Merged

Typed decorators #2981

merged 9 commits into from Apr 22, 2021

Conversation

wyozi
Copy link
Contributor

@wyozi wyozi commented Apr 5, 2021

Again a quite strong type change, but I think an important one as well for type safety. This would mean that all decorators must be explicitly typed in the interface to go through without as any hacks. Looking for comments about this approach

Checklist

@github-actions github-actions bot added the typescript TypeScript related label Apr 5, 2021
Copy link
Member

@jsumners jsumners left a comment

Choose a reason for hiding this comment

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

Does this mean any plugin a TS user loads will have to have TS types exported?

@wyozi
Copy link
Contributor Author

wyozi commented Apr 5, 2021

@jsumners ah yeah, this change would mean that plugins that don't export types in the correct format would start causing TS compiler errors. That's not ideal.

Alternative that I'm doing in my codebase right now is a separate typedDecorate function on FastifyInstance. It's slightly annoying to have two functions for the same thing, but I'm trying to have as strict typing as possible everywhere I can.

Copy link
Member

@mcollina mcollina left a comment

Choose a reason for hiding this comment

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

I'm -1 for this change, it's too breaking.

Copy link
Member

@jsumners jsumners left a comment

Choose a reason for hiding this comment

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

👎

Plugins cannot be required to be TS specific.

@wyozi
Copy link
Contributor Author

wyozi commented Apr 5, 2021

@mcollina @jsumners I thought of a better way to make this work.

Now there's two type declarations for decorate: one for when the key exists in the interface type and fallback for when the key doesn't exist. This way the stricter typechecking will only kick in when the decorator key is found in the real type interface. It's not perfect but it shouldn't break anything while still allowing stricter type checks when possible.

What do you think?

@jsumners
Copy link
Member

jsumners commented Apr 5, 2021

one for when the key exists in the interface type and fallback for when the key doesn't exist.

I don't know what this means. But if it doesn't break JavaScript plugins, then I am okay with whatever @fastify/typescript decides.

Copy link
Member

@Ethan-Arrowood Ethan-Arrowood left a comment

Choose a reason for hiding this comment

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

can you add some type definition tests to demonstrate how this is meant to work? Additionally, I think you'll need to make some doc updates.

types/instance.d.ts Outdated Show resolved Hide resolved
@github-actions github-actions bot removed the typescript TypeScript related label Apr 6, 2021
@wyozi
Copy link
Contributor Author

wyozi commented Apr 6, 2021

Added some tests and a mention in TS docs about decorate typechecking

Copy link
Member

@airhorns airhorns left a comment

Choose a reason for hiding this comment

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

I like this approach! I think it is a good balance between allowing explicitness if folks want to opt in without requiring it, which is the same aesthetic as TypeScript itself seems to use.

AFAICT this is still a breaking change in that projects might no longer typecheck if their declarations don't match their decorations. But, that is a real problem if you ask me, and worth identifying. Dunno if that qualifies as semver major but we should definitely add a note to the change log and instructions for remedying the issue.

expectError(server.decorate('functionWithTypeDefinition', (foo: any, bar: any) => {})) // error because invalid return type
expectError(server.decorate('functionWithTypeDefinition', (foo: any, bar: any) => true)) // error because doesn't return a promise
expectError(server.decorate('functionWithTypeDefinition', async (foo: any, bar: any, qwe: any) => true)) // error because too many args
server.decorate('functionWithTypeDefinition', async (foo, bar) => true)
Copy link
Member

Choose a reason for hiding this comment

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

Could you add a type assertion on the type of foo inside this function? Would be good to test that it is inferred properly

@mcollina
Copy link
Member

mcollina commented Apr 6, 2021

i would prefer if this targeted the next branch instead

@jsumners
Copy link
Member

jsumners commented Apr 6, 2021

i would prefer if this targeted the next branch instead

Even then, I would be open to a rollback if it breaks the overall ecosystem.

@wyozi wyozi changed the base branch from main to next April 6, 2021 21:50
Copy link
Member

@mcollina mcollina left a comment

Choose a reason for hiding this comment

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

lgtm

@mcollina mcollina added v4.x Issue or pr related to Fastify v4 semver-major Issue or PR that should land as semver major labels Apr 7, 2021
Copy link
Member

@delvedor delvedor left a comment

Choose a reason for hiding this comment

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

I like this change, and I agree it should be treated as semver-major.

@mcollina
Copy link
Member

mcollina commented Apr 9, 2021

@Ethan-Arrowood could you take a final look?

test/types/instance.test-d.ts Outdated Show resolved Hide resolved
test/types/instance.test-d.ts Show resolved Hide resolved
Copy link
Member

@RafaelGSS RafaelGSS left a comment

Choose a reason for hiding this comment

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

LGTM.

Copy link
Member

@Ethan-Arrowood Ethan-Arrowood left a comment

Choose a reason for hiding this comment

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

LGTM 😄

@mcollina mcollina merged commit 2f23866 into fastify:next Apr 22, 2021
@wyozi wyozi deleted the patch-1 branch April 22, 2021 20:38
@github-actions
Copy link

This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 23, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
semver-major Issue or PR that should land as semver major v4.x Issue or pr related to Fastify v4
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants