-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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
🐷 Implement lazy versions of Path and ArrayPath #7311
🐷 Implement lazy versions of Path and ArrayPath #7311
Conversation
@bluebill1049 I've implemented the types I am a fairly new to
Seeing that there aren't any comments outside of test cases, how should I document those new types? |
Hi @felixschorer this is great stuff, thank you! Actually the more comments the merrier on these types, so please from the top of each add a jsdoc explanation (I would like to do them for all of them, but at minimum your new ones you added). Separately question: did you see this in another codebase? They look different to me from the ones we saw in ts-toolbelt.. |
Honestly, this is really impressive! ✨
💯 Would be great to have some test coverage for those types.
Yes, please add comments. That would be really helpful. Additional: We also have a lot of integration tests (unit/automation) as well, so probably would catch those issues early as well once you start applying those lazy paths look up. |
@barrymay I wrote those types from scratch.
Are you implying that I stole that code from somewhere? |
@felixschorer I am pretty sure barry didn't mean that. I think he was just surprised with all the types that you have written so far. |
No offense taken. I am not a native speaker, so I may have interpreted it differently than how it was meant. It's also the middle of the night 😅 |
Indeed I am appreciating (so does the community) the contribution and work that you have been putting this. It's going to be a huge improvement! |
Are you implying that I stole that code from somewhere?
Again, thank you so much for the work - as Bill said, it's a huge benefit to the project!! |
@bluebill1049 Would it be possible to add a type assertion library as a dev dependency? Testing for type equality is sadly not that trivial due to a lot of edge cases. I'd rather use a library for that instead of rolling my own.
Also, which version of |
@felixschorer have you checked out https://github.com/SamVerschueren/tsd? I've heard quite a number of refs to it and I was hoping to consider that route (it was also mentioned by a Microsoft contact we heard from a few days ago) It's somewhat of an extra test step but I feel well worth considering |
All that said https://www.npmjs.com/package/conditional-type-checks is quite nice as a simple checking ts lib and on its face seems perfect. My only concern is whether it's getting actively maintained, but if it works fine and is simple enough Im fine with it. |
@barrymay I have tsd on my radar. I actually mentioned it in my comment but then removed it again in the edit. I haven't used it yet, but from what I've seen you need to run a script to execute the type tests instead of getting compile time errors. It also seems to be awkward that one has to create a value first. Honestly, I didn't want to mess with build pipeline 😅 |
Ha - testing ts types is awkward to start with, so I totally get it! I'd be thrilled if you took Tsd for a spin and see what you thought, it's hard to overlook it, just haven't personally had time to integrate yet. Considering the (awesome) new types your introducing here, I think it's a perfect time to try it. |
thanks, @barrymay's input. I just quickly checked both they are both actively maintained, and syntax wise both are quite similar too. Consider we don't have a type assertion library at the moment. I am keen to take either onboard. Another great add-on we always talked about but never implemented. Really exciting stuff. |
…evaluate-paths # Conflicts: # CONTRIBUTING.md # yarn.lock
} | ||
|
||
/** it should work on unions */ { | ||
const actual = _ as SplitPathString<'foo.bar' | 'bar.foo'>; |
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.
oh nice! union works as well
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.
They all work on unions 😅
const actual = setter('foo', 'bar'); | ||
expectType<string>(actual); | ||
} | ||
} |
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.
at least 100 plus tests for all the types! impressive ✨ wish we had this earlier.
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.
It should be closer to 200 I think. It was 182 last time I've checked.
Edit: Checked again 197 (in total across all files)
This is truly an amazing piece of TS work along with great tsd testing and superb jsdoc comments. I need a couple days to finalize my review but this change makes RHF so much stronger. That said @bluebill1049 if you want to put a beta out with this code so ppl can check it out I'm fine with that. |
Thanks, @barrymay sorry to take a bit longer to review this. If you are happy with this PR I can merge it into the branch and publish a beta first. (In addition, i was hoping to hear some feedback from Kotaro as well, but happy to merge first as it's holiday season right now) :) |
@bluebill1049 @barrymay This PR doesn't change the function definitions yet. It just adds the types. They are currently unused, so releasing a beta is a bit pointless 😅 |
To keep the individual PRs manageable (this one is already too large imo) my plan would be to split the work like this:
|
sounds good to me @felixschorer I will merge this one in first, I will keep reading the code and probably asking you questions. at this can unblock the rest of the feature. |
* 🐷 Implement lazy versions of Path and ArrayPath (#7311) * Extract path related types from types/utils.ts * Implement types for splitting and joining paths * Extract KeyListValue from PathValue * Rename KeyListValue to EvaluateKeyList * Implement Keys to get the keys of a container whose value is U * Add Traversable as the opposite of Primitive * Implement LazyPath and LazyArrayPath * Implement LazyFieldPath and LazyFieldArrayPath * Move Keys & Rename PreviousSuggestion and NextKeySuggestions * Differentiate between AsKey and ToKey * Remove unnecessary wrapper types with default types * Add doc strings for internal types * Add doc strings for lazy types * Use consistent wording * Add doc strings for eager types * Add tsd * Exclude src/*.d-test.ts and src/*.d-test.tsx from TS compilation * Revert "Exclude src/*.d-test.ts and src/*.d-test.tsx from TS compilation" This reverts commit ebedf7f. * Revert "Add tsd" This reverts commit 1546e35. * Add ts-expect * Add expectTypesEqual helper * Add type tests for internal types * Extract EvaluateKey from EvaluateKeyList * Group tests by type * Export internal types to test them * Rename CompletePathString to SuggestPath * Add tests for lazy paths * Test that ValidKeyListPrefix is tail recursive * Use tsd for type tests * Exclude type test files from compilation * Remove Expected type alias for better error messages from tsd * Remove calls to describe / it * Use type assertion instead of call to type<>() * Fix TS failing to infer the PathString in certain cases * Replace default type parameters with Impl types * Make AutoCompletePath distinct from SuggestPaths * Simplify SuggestChildPaths type * Remove Actual type alias for better error reporting from tsd * Add type tests for eager types * Fix ArrayPath tests * Fix LazyArrayPath accepting primitive arrays and tuples * Fix EvaluateKey and EvaluateKeyList not behaving as expected on unions * Fix EvaluateKey handling tuples not correctly * Fix TS2589 for SuggestChildPaths * Fix EvaluateKeyList causing TS2589 * Fix EvaluateKeyList converting any to never * Change EvaluateKeyList to resolve to undefined whether a path does not exist * WIP Fix Keys not working correctly on unions * Fix Keys & add tests * Move test case from Keys to ObjectKeys * Add default for constraint type for ObjectKeys and NumericKeys * Rename KeyList to PathTuple * Add defaults for constraint types * Move Keys to common.ts * Return never from EvaluatePath if a path doesn't exist * Test EvaluateKey and EvaluatePath with index signatures * Fix EvaluatePath resulting in huge types * Fix WS burning CPU cycles * Use HasKey instead of conditional * Add tests for HasPath * Inline DropLastElement and add tests * Test that Suggest* work as expected on unions * Don't suggest paths when a union is passed to AutoCompletePath * Fix Keys omitting optional keys * Test that EvaluateKey can handle optional properties * Fix Keys returning never for nullable types * Fix type tests * Fix Keys constraint matching optional properties when undefined is excluded * Move ContainsIndexable definition closer to where it's used * Fix handling of null in Evaluate* * Fix EvaluateKey not traversing through array methods * Remove unnecessary optimization * Fix child paths not being suggested if they are nullable * Remove unnecessary never check * Fix LazyArrayPath not accepting nullable arrays * Simplify NumericObjectKeys * Rename TupleKey to TupleKeys * Test that EvaluateKey handles null and undefined * Revert PathValue to its former definition * Run API Extractor * Add tests for handling any * Fix blank keys being accepted * Add missing doc string for AppendNonBlankKey * Remove S flag from AutoCompletePathImpl by extracting AutoCompletePathCheckConstraint * Amend comment on AutoCompletePathCheckConstraint * Fix AutoCompletePath accepting malformed paths * Test that AutoCompletePath behaves correctly for never and any * Remove unnecessary check for empty string * update lock * udpdate API extractor * udpdate API extractor * udpdate API extractor * avoid md file with prettier * 💻 Feature/avoid omit key name use field array (improve DX) (#7301) * skip omit keyName when value is presented * fix variable name * remove all ts-ignore * wrap validate inside field check * update deps * revert change on package.json * remove lazy path Co-authored-by: Felix Schorer <felixschorer@users.noreply.github.com>
Implements lazy versions of
Path
andArrayPath
as suggested in #7290The project does NOT make use of these types yet. They just exist for now. Integrating them into the API is subject of another PR.
types/utils.ts
->types/path/common.ts
/types/path/eager.ts
)Path
->LazyPath
,ArrayPath
->LazyArrayPath
)tsd
for type testingtsd
into the build pipelineLazyPath
andLazyArrayPath
Both types validate paths (e.g.
'foo.bar.42.baz'
) against a type and return a union of suggestions which may include the given path if it is valid. They're supposed to be used on function arguments.before
after
By using those types on function arguments, the path will be validated against
T
. I.e. TS will report an error when the path does not exist withinT
. Also, only the immediate successor/child paths will be suggested to the user when typing. PreviouslyPath
would report all possible paths, resulting in bad DX for large types.Typescript below version 4.5
The new types are implemented tail recursively which allows TS to do some optimizations on them. I've tested the types under TS 4.3 and TS 4.4 to make sure that these optimizations aren't needed for the types to work properly. There is also no noticeable difference in performance.
Index signatures using template literal types aren't supported in TS 4.3. The test cases explicitly testing that feature fail under TS 4.3.
IntelliSense
WebStorm and VS Code will show the path suggestions in a dropdown while typing.
Should a path be rejected, neither (WS or VSC) will show the expanded union of suggested paths when hovering over the error.
The error message will some times include "Did you mean ...?", but not always.
WebStorm
VS Code
Import changes
Since a few types have been moved to different files, there may be breaking changes for users which imported these types by their full path.
This could be solved with a re-export in
types/utils.ts
.