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

fix: add AbortController to the terminal types list #47

Merged
merged 4 commits into from
Oct 11, 2022
Merged

fix: add AbortController to the terminal types list #47

merged 4 commits into from
Oct 11, 2022

Conversation

micalevisk
Copy link
Contributor

I've made this change on @nestjs/config: nestjs/config#907 I found that it closes #46 as well

@micalevisk
Copy link
Contributor Author

micalevisk commented Oct 8, 2022

@Papooch do you mind adding the label hacktoberfest here? 😄 (or just the hacktoberfest topic to the repo)

@Papooch
Copy link
Owner

Papooch commented Oct 8, 2022

Thanks! Do you think that fix eliminates the need for the Terminal type altogether?

do you mind adding the label hacktoberfest here?

I added the hacktoberfest to the repo labels, is all there's to it?

@micalevisk
Copy link
Contributor Author

micalevisk commented Oct 8, 2022

is all there's to it?

yep, thanks :)


I tested the following without the Terminal; didn't worked

image

image

Also, those comments up there are the types that we got when using this PR's code

@Papooch
Copy link
Owner

Papooch commented Oct 8, 2022

Hm, it should not expand on the string methods 🤔. Does it also happen without your changes?

Also I'm wondering if we just put a constuctor type (new (...args: any[]) => any) to the TerminalType, whether that would fix most of the deep types issues. I don't see a reason to generate paths inside a class instance.

@micalevisk
Copy link
Contributor Author

ok so without the changes I've made. I add that to the TerminalType but it didn't solved the infinite issue

@micalevisk
Copy link
Contributor Author

(with this PR's changes)

image

as you could see, those any are due to the union with undefined on bar

@Papooch
Copy link
Owner

Papooch commented Oct 8, 2022

Hmm. I think we need to take a decision here. Even if you define all properties of the ClsStore as required, you can still get undefined when you try to retrieve them, if you don't populate all of them before accessing.

So if the types were to be 100% correct, then every cls.get should be return T | undefined. But that requires a lot of unnecessary null checks at the use-site, even if you know you have set up the store correctly, so that's why I chose this way.

Having an explicit nullable property in the store is something I didn't consider, but it makes sense actually.

I'm prety sure there's some typescript trickery that will still allow generating the paths for the nested properties, but make the return type nullable.

At the same time (and that's for a separate issue), we should never generate paths inside classes.

@micalevisk
Copy link
Contributor Author

good point.

Here's the project (patched) that I'm playing with: https://gitlab.com/micalevisk/nestjs-cls-issue-46

just run npm ci and checkout the src/app.service.ts file.

I'll try to make them return undefined later

@micalevisk micalevisk marked this pull request as draft October 8, 2022 18:36
@micalevisk micalevisk marked this pull request as ready for review October 9, 2022 14:37
@micalevisk
Copy link
Contributor Author

micalevisk commented Oct 9, 2022

since ClsService#get could always return undefined, can't we just add an union with undefined below?:

): TypeIfUndefined<R, TypeIfUndefined<typeof key, S, AnyIfNever<P>>, R>;

image

@micalevisk
Copy link
Contributor Author

micalevisk commented Oct 9, 2022

Another approach to avoid typing non-null assertions would be the same used in @nestjs/config: adding a optional flag type-arg on ClsService generics.

I can't think on anything other than those two :/

@micalevisk
Copy link
Contributor Author

micalevisk commented Oct 9, 2022

now we have

image

image

here's the TS playground

@Papooch
Copy link
Owner

Papooch commented Oct 10, 2022

Sorry for taking too long to respond, I finally found some time to look into it.
It seem there is really no way to implicitly stop path generation inside instances of a class, but it seems that at least your fix prevents the typescript error, while still generating paths inside the AbortController, which is undesirable IMHO.

I am actually fine with adding AbortController to the TerminalType union if there's no way to weed out class instances automatically. Come to think of it, I'm fine with adding all JavaScript/Node.js built-ins - these are no different than Date or Map constructors.

As far as this PR goes, I think we can just merge it (unless you want to do some polishing) and address the other things in separate issues.

since ClsService#get could always return undefined, can't we just add an union with undefined below

I don't really believe in 100% type correctness at the expense of usability. As I said, this would pollute the code with null checks which add little value if your app is built around having stuff in the context. I'm more inclined towards your other suggestion with the strict flag. Moreover, I would probably straight up throw an exception by default, unless the strict flag is set to false - which should also change the return type. Then even the types would match.

However, either of these approaches deal with the possibility of nullable properties in the ClsStore. Either everything is optional, or everything is required unless you turn off strict. But since the store is user defined anyway, they should know how to work with it.

The typing of ClsService definitely needs some overhaul, but it will most likely result in a breaking change.

@micalevisk
Copy link
Contributor Author

micalevisk commented Oct 10, 2022

which is undesirable IMHO

oh, I misunderstood you before. Now I got it that the .get() should behave like Map#get, my bat.

I'll revert that so we could merge this now as a hot fix. And I'll try to improve the solution around your thoughts later, is it ok for you?

@micalevisk
Copy link
Contributor Author

now we have this:

image

I guess that's it.

@micalevisk micalevisk changed the title fix: stop when RecursiveKeyOf has found any fix: add AbortController to the terminal types list Oct 10, 2022
@Papooch
Copy link
Owner

Papooch commented Oct 10, 2022

I mean you didn't really have to remove the "stop if we found any". If anything, it prevent the error, which is nice. What I meant was that it was undesirable to generate paths inside AbortController, hence the suggestion to add it to TerminalType.

@Papooch Papooch merged commit f88d255 into Papooch:main Oct 11, 2022
@micalevisk micalevisk deleted the fix/recursive-type-evaluation-on-any branch October 11, 2022 22:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

tsc error 'Type instantiation is excessively deep and possibly infinite' when using AbortController
2 participants