-
Notifications
You must be signed in to change notification settings - Fork 28
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
Add babel macro #24
Add babel macro #24
Conversation
959be40
to
86cb1d6
Compare
I squashed-merged #23 , so you'll need to rebase, but it looks like maybe you already did.
Yes, definitely good to include instructions and an example in the README.
I think I understand what you mean. The naming of Actually,
Might this be clearer? Keeping
Sounds sensible.
Splitting It seems fairly easy to avoid a dependency on Would that be OK?
Bringing in The rest of the checklist sounds like TODOs to yourself. Thanks again! I agree this is quite cool. I only wish I could do it within typescript :) |
@dsagal Thanks for the prompt initial review! Great to have feedback early on. Also thanks for reading and addressing the issues I listed!
Yup I rebased it as soon as I saw the other PR was merged 👍
Definitely. The codesandbox I have is less of an example of "How to use" and more of live demo showing it in action in a realistic scenario, so I will include both a short/minimal "How to use" example, and a link to the codesandbox demo. Here it is: Since there will be a link to it in the README (if that's ok), can I get you to take a quick peek at it and give any feedback? P.S. I'm ok to move the repo (zenflow/ts-interface-builder-macro-demo) to the gristlabs org if you want.
As, yes, I meant Yeah, so if we have Of course, in the README, I will start with documenting
Excellent. We can do this just before merging, to minimize the chance of merge conflicts (in case another PR with changes to
Ah yeah, totally. I didn't think it would be such a big dependency as it turns out, and just included it because other babel macros do. Let me work on this and I'll give you an update in a bit.
Great! I can mark the "discuss" item as done now. |
@dsagal Fixed with ed8633d. I moved the macro to Regarding my 2nd TODO ("split So I guess we should have Or can we make a possibly breaking (but not likely breaking) change to organize things better? We could drop the |
The codesandbox example seems pretty cool. As far as feedback, I guess it depends on your main goal. Just to showcase the functionality, it's a bit big -- you have to know what to look for to notice in the code the the validation provided by the building + checking of interfaces. We could have a much smaller example, but I agree that this one is more realistic in that validation's main use case is when there is communication. My main "review" comment for that example code is to add explanatory comments -- particularly to the code that's relevant to using the new macro. I'd say you should keep it as your own repo. We'll link from the instructions. In fact, if you prefer, you can also create your own repo for |
@dsagal Yeah, I wouldn't mind making it a separate repo & package under my ownership. It would be a nice gem for my GitHub profile and it would allow me to maintain it directly without always the need to bother you. Its also kinda the more modular way to do it. The main practical benefit that I see there is that each ( My only reservation is that as part of the Should we add another option for Or should we just agree that the |
561c7d9
to
93a30a0
Compare
@dsagal Ok I rebased all my work onto my branch for #26 (which is based on the current
|
@dsagal Really sorry I ended up rewriting the whole commit history for this PR... I really get annoyed when people do this to me.. (it kinda invalidates the changes I already reviewed, and I have to review everything all over again) so I don't know why I did it here. 😛 I'll restore the branch with it's original history now, and push a new branch with all updates & a condensed commit history: add-babel-macro-2 Let me know if you would like me to apply those updates to this (original) branch so you can easily see what's changed. I'm happy to do that, even if we decide this will be a separate package, just to use GitHub PR to get your code review. Sorry again. |
93a30a0
to
561c7d9
Compare
@dsagal I added some explanatory comments, but yeah I think you're right that it's a bit overkill. I'll make a different, more minimal, live working example when I'm writing the documentation. Maybe a similar interface, but just checking the user's JSON input in the browser (no API requests)? And using a simpler example TypeScript interface? |
@dsagal That made me sad to hear, so I did a bunch more research. As it turns out, this could be implemented this as a TypeScript transformer instead of a babel macro, which you might be able to use, if you can substitute the BTW I hit a gold-mine of other projects that do things similar to ts-interface-checker/builder: https://www.reddit.com/r/typescript/comments/i8yk6i/validating_objects_type_at_runtime/g1cleg3/ |
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.
BTW, my delay in responding wasn't to nudge you towards making it a separate repo :) Just regular being swamped :)
Should we add another option for
format
like"js:expression"
that just outputs the type suite expression without that commonjs wrapper?Or should we just agree that the
format: 'js:cjs'
output won't change from how it's described above?
I have no problem with either. I kind of like js:expression
idea (except that the mention of undeclared t
would be a bit awkward, so maybe it should output a function(t) { return {... t.iface(...) ...}; }
?) But at the same time, if js:cjs
works for you, I think we could keep it from breaking with a little test case containing a comment what it's protecting against.
No worries about rebasing. I'll re-review from scratch, since it's been too long to be fresh in my mind, and a lot of code moved around between files anyway.
As it turns out, this could be implemented this as a TypeScript transformer instead of a babel macro, which you might be able to use, if you can substitute the
tsc
CLI command withttsc
, or if you use the TypeScript compiler programatically. This doesn't work for all situations obviously (just the aforementioned situations), but could cover some situations, just like the babel macro.
Hmm, interesting... Maybe some day someone will do that. Seems promising.
BTW I hit a gold-mine of other projects that do things similar to ts-interface-checker/builder: https://www.reddit.com/r/typescript/comments/i8yk6i/validating_objects_type_at_runtime/g1cleg3/
That's a lot of projects :) Well, I am glad you still like this one! :)
OK, on to reviewing.
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.
Looks really good, thank you!
I'll cross these 2 items off the TODO list in my opening comment:
Like the original text explains, this isn't really necessary. I don't think it's worth the bit of complexity either.
The macro module is loaded by |
@dsagal Well it's a tough decision for such an arbitrary one, but I think that the babel macro has more of an advantage being part of this package rather than being separate. As long as you don't mind that the macro doubles the size and complexity of this package. I'm confident we can do a good job maintaining it together. Assuming that you're still cool with that (merging this PR to make the babel macro part of this package) then I think all that's left to do is close out the above threads and update the README? Anything else you'd like to add? |
I am cool with that, and since the code changes seem finished, I went ahead and merged. Changes to README can go into a separate commit. |
@dsagal Awesome! I'll follow up with the README updates and then I guess we can publish a new version 🚀 It makes sense to update the README for ts-interface-checker too right? That README seems to have the overall usage instructions for ts-interface-builder+ts-interface-checkers. |
Agreed. I suggest adding a separate documentation file with a detailed description of the macro usage, with examples, babel config, etc. And in the ts-interface-checker main README, include an overview with brief example, just enough to appreciate it and use it, and link to the detailed file. The bit in ts-interface-builder could literally be a one-liner with a link to the overview ts-interface-checker README and to the detailed doc. |
@dsagal I was looking at ts-interface-checker's README and how to just "update" it in regards to the addition of the macro (not just insert a new section). I came up with gristlabs/ts-interface-checker#31. I feel like going into detail (like usage examples) about both methods (cli & macro) is a lot of extra info that actually belongs to ts-interface-builder. I think even the part in my PR that describes the 2 methods (cli & macro) is not really necessary, since all that is really necessary is to to say "use ts-interface-builder to get type suites". What do you think? Regarding README updates in this repo (ts-interface-builder), it seems that the README for the most part (the whole "Usage" section) could be rewritten/reorganized (with all the current information) such that we describe the purpose & usage & behavior of the package in general (things that apply to both the CLI & the macro) & then have section (or file) for the CLI usage & a section (or file) for the macro usage. |
I responded to the ts-interface-checker proposal in that PR. As for "cli" vs "core" documentation, it sounds sensible, but looking at ts-interface-builder's README today, there is pretty much only "cli", so I am not really sure what you mean by "core". E.g. an example of a type suite could be core, but it's not really visible to the user when using the macro. In general, I think a good README is one that can be read incrementally -- start with what's it about, and how to get started quickly (some readers in a rush will stop there), give some examples (for readers looking for more clarity), then have more sections with more details (for those who need it). Now that there are two different ways to get started quickly, I think it's still good to present them briefly near the beginning, then give more explanation and the details of each method. |
Yep, an example of a type suite would be "core". Even though it's not visible in any file when using the macro, it's still every bit as relevant for the macro user as it is for the cli user. As a macro user you generally want to know how it works, and what the output looks like. The type suite example isn't strictly necessary in either case (cli or macro) (with the cli, the user could just import & use the generated module without ever looking at the contents) but is helpful for understanding how the system works. So I think that info (example type suite for a given TS module) can be covered in the intro section (and also included in examples in the CLI Usage & Macro Usage sections). There is not much else under "Usage" that isn't talking specifically about the CLI.. just a few statements in the first paragraph like "This module works together with ts-interface-checker module". I want to move those to the intro section. Since you seem to agree with the principle of separating "core" documentation & cli documentation & macro documentation (and since we're definitely on the same page regarding your second paragraph), I will try a PR to see what you think :) |
You know what? Screw that.. we can keep "type suite" an abstract idea in the intro section, and make it concrete in both CLI Usage & Macro Usage. The intro section just needs to introduce the idea of a type suite.. no example is necessary for a high-level understanding. |
This is based off my branch for PR #23 since it uses
format: "js:cjs"
under-the-hood. I believe when that PR is merged, those commits will stop appearing in this PR.. If I'm wrong I can rebase and fix it for review.I'm testing it out with a little demo project and it works beautifully! I am very happy! I will share it via codesandbox after a bit more work. Maybe this can be included as a link in the README.
There are still some issues, a couple of which I need help with:
makeCheckers(...): ICheckerSuite
, also offer editbuildTypeSuite(...): ITypeSuite
, to give the option of more control to users, and so they can possibly build & compose/merge multiple type suites and callt.createCheckers
directly with the result.splitNot needed. Made a separate entry-point for the macro.lib/index.ts
intolib/{Compiler,bin,macro,index}.ts
- Now that the CLI is not the only consumer of theCompiler
, we should reorganize things a bit before merging. I suggest keeping a single entry-point for the build (i.e.lib/index.ts
), as it is now, to keep things simple. That entry-point would just export the exports ofCompiler.ts
,bin.ts
, andmacro.ts
. @dsagal Does this sound ok? If so, I will make the change just before merging.ts-interface-checker
asdevDependency
.This is a notable change I thought would be worth bringing up.
I think it makes sense and even we might want to do some integration testing on the
ts-interface-builder
side.The motivation here is that the TypeScript checking for the related test fixtures (which my IDE does automatically)
breaks when the
ts-interface-checker
package is not installed, due to its import inmacro.d.ts
.It's not strictly necessary, but it's nice to see that everything is compiling & working as expected.
@dsagal What are your thoughts?
add ability tomakeCheckers('some-npm-package')
? Not strictly necessary since you can alreadyimport {SomeThing} from 'some-npm-package';
and then usemakeTypes().SomeThing
(no first argument to makeTypes means build the current ts module).issue:test/test_index.ts
tests the source (i.e.lib/**
), whiletest/test_macro.ts
tests the build (i.e.dist/**
). Can that be fixed so both test the source?