-
Notifications
You must be signed in to change notification settings - Fork 5
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
Adds strict type definitions to sprintf #18
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for submitting this so quickly. At a glance, it all looks great, and pleasantly surprised how simple it turned out.
I'll try to get this merged and published sometime this weekend, along with some other general maintenance work (dependencies, etc.).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This works great! I was able to test it against the examples in __tests__/index.js
. For whatever reason, I originally exempted __tests__
files from type-checking, so they weren't run by default. But adding // @ts-check
manually to the top of the file helped in validating the types. There's a lot of type errors in the edge case handling, but I think that's expected (desired, even).
Actually, one valid usage that looks to be unsupported now by these types is this one:
References:
How feasible might it be to include support for this? |
Hi @aduth, ah you are right, and actually I noticed that even in this case it is not correctly strictly typed I am trying to fix it both the issues |
The issue I see, you need to know the types that are to be extracted, if you don't have a good delimiter. And there are a large number of different specifiers. The only reason extracting type Values<T extends string> =
T extends `${infer _}%${infer K}${infer Rest}`
? K extends Spec
? [ Specifiers[K], ...Values<Rest> ]
: Values<`${K}${Rest}`>
: [];
That article says it was inspired by react-router typing, I took a look at those. Check this out, react router has it easy, they have super clean delimiters in the url. Path extends `${infer L}/${infer R}` |
My assumption, to support the large number of possibilities would require a deep set of conditional type checks, accounting for each. |
@johnhooks, The reason for the match is that K is a specifier from a given set of specifiers. The type inference mechanism detects which specifier is used and determines the corresponding type accordingly. The match ends when the template literal pattern no longer finds a % followed by a valid specifier, indicating that there are no more specifiers to process in the string. |
I see where { [K in Key]: Specifiers[Spec]} Though the The UPDATE: So in the more complex instances, my assumption the inference of T extends ${infer _}%${infer K}${infer Rest} |
@johnhooks, you're probably right. I'll work on improving the string matcher to better define the various cases. |
As discussed in the linked issue #15 , This PR aims to add strict definitions for sprintf
Compared with the proposed modification that I showed in the related issue, I have made a small change since i noticed that also an array is accepted as argument (basically adding this
SprintfArgs<T>[]
).As mentioned, it can be considered a breaking change because the overload with the spread operator (es6) is not supported by IE.
I am not able to move the imports to the beginning of the file as @johnhooks showed me recently (but maybe he could help me with that), it should make that jsdocs code block a little less ugly
should work in this way:
close #15