Repository navigation
Design Meeting Notes, 5/10/2023 #54228
Copy link
Copy link
Closed
Labels
Design NotesNotes from our design meetingsNotes from our design meetings
Description
Transformer Plugins
- Concept in the TypeScript API called
customTransformers- You can provide transformers before and after for JS output files, and after declaration files.
- Can we support this via the
tsccommand? - We released 5.0 recently, but it broke a lot of how people do patching.
- Main reason people do patching (Yarn aside) is doing custom output transformers.
- These transformers pass in the
Program- are they effectively doing type-directed emit?- Is type-directed emit a bad thing?
- You need an
EmitResolverfor something like runtime type-checks, or minification, or whatever. - [[Discussion on philosophy of "statically analyzable" emit vs. "type-directed" emit]]
- Some of why type-directed emit is "bad" is because we don't have the full program.
- Another is that we're not sound.
- TypeScript itself had to avoid type-directed emit due to these factors and out of trust - when you write JavaScript in TypeScript what you get is what you see!
- But when you use a plugin, the problems are
- They might be slow.
- They might do the wrong thing, often because of unsoundness.
- And when that happens, people may kvetch and we have to say "yeah we know, we said that you".
- But when you use a plugin, the problems are
- If we're doing watch plugins, it feels like transformer plugins.
- And then module resolution plugins?
- 😬
- And then module resolution plugins?
customTransformshave existed for over 5 years, always been an asymmetry (if not just annoying) that you have to use a bundler or write a wrapper fortsc.- Feels like the safest plugins to most dangerous are transforms, watch, and module resolution.
- Some feel the opposite.
- Why?
- Transforms are fairly linear. Watchers can bork state of the program, module resolution leads to an incorrect program, and most people don't know the real scope of what you need to support resolution correctly.
- Other reasons: resolutions from Deno, Yarn, etc. would not fit into most resolution strategies.
- Proposal:
- Build on the
pluginsarray. typeis a new field for each plugin entry.- Maybe transform plugins get
"type": "transform"or whatever. - Maybe Watch plugins get
"type": "watch" - Try not to conflict with ts-patch or others who currently use
plugins
- Maybe transform plugins get
- First step - allow users to provide
customTransformers. - All of this on the command line requires some new
--allowPluginsflag.
- Build on the
- Come back to this at next meeting.
Type Argument Placeholders and Feedback
- Changing overload resolution broke a ton, so we backed off of the "partial type argument" thing.
- Lots of people watching Implement partial type argument inference using the _ sigil #26349 - but all with different needs.
- People saying "I have a type argument that never should be specified"
- Translates to "We need an existential at this location"
- People really don't want users to write
foo<SomeType, _, _, _>even if it's an improvement fromfoo<SomeType, VeryLongType, VeryLongType, VeryLongType>- Flow has existentials, Rust has
impl traittypes, etc. - But existentials act as something that adds quite a bit of work to every call.
- Also, not full agreement here that everyone on the issue is looking for this feature.
- Flow has existentials, Rust has
preferinfer?- Using type argument defaults means that we fall back to the default itself if it's not specified - so
preferinfersays "no no no, the default isn't desirable. You want this thing to be optional, but to use inference as a fallback if it's not specified".- That's almost always the behavior you want.
- New type param modifier to allow for partial inference based on signature declaration #53999
- Switches internal compiler behavior, but doesn't have a strong type theoretic foundation.
- Using type argument defaults means that we fall back to the default itself if it's not specified - so
- Feels like people want a local type alias.
- But type alias wouldn't provide inference sites.
- We don't feel great about
preferinferat this moment - it feels like the scope is narrow.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
Design NotesNotes from our design meetingsNotes from our design meetings
Activity
Andarist commentedon May 12, 2023
i wouldnt say that - i think that many in the PR comments welcome this improvement. It’s just that many think (myself included) that for certain use cases it feels like a needless requirement put on the final consumer of the API. Some APIs are just designed in a way that would require this at call site - and at that point, why not allow it somehow to be the default behavior of the signature?
If i have to say to all of my users “u need to use
_as a type arg every time u call this function” then I will say that to them. It’s just that i would prefer it if i wouldnt have to because its one more thing they have to remember when interacting with my codessalbdivad commentedon May 13, 2023
Just wanted to reiterate that as Mateusz Burzyński (@Andarist) suggests, I am a big proponent of incremental progress so long as there is a consensus around how it could eventually fit in to a full solution👍
fatcerberus commentedon May 13, 2023
I think these two passages are effectively saying the same thing. i.e. "Yeah, it's an improvement, but I'd really prefer if there was a better way..."
I suspect this is exactly the reason for the caution here - if said incremental progress involves a new feature, then the way to use that feature now has to then be maintained for backward compatibility even if a different, better way comes along later--and now you have multiple ways to do the same thing (even though one of the ways is effectively legacy baggage) and people get into unproductive style wars over it. So I'm only for incremental progress if what's implemented now is a proper subset of what all will eventually be implemented.
fatcerberus commentedon May 13, 2023
I'm quite amused by this because it reminds me of when people write unsound generic functions/classes and then get confused when the compiler yells at them. The compiler knows the function isn't safe but the coder doesn't realize that because they're only thinking of cases where the type parameter gets inferred. There's no type theoretical basis for that kind of thinking (a type parameter implies universal quantification), but that's what ends up happening simply because TypeScript's design makes explicit type arguments an antipattern.
Andarist commentedon May 13, 2023
Maybe i misread the design notes late in the night - it read to me a little bit as if we were not recognizing
_being an improvement. So I wanted to assure the team here that it's definitely an improvement already but we just wish for some further improvements for our use cases. It feels that_is definitely in the right direction because it doesn't preclude further improvements - so whatever we land on (if anything) to address our concerns shouldn't really clash anyhow with_(it would still be helpful for other use cases).RyanCavanaugh commentedon May 16, 2023
I would just echo this 100 times over, because the entire reason we're in a difficult spot here in the first place is that generic defaults were sort of rushed in, when we should have really done partial inference for unspecified type parameters instead. it's significantly easier to do the right version of a feature first than to do the OK version and then a better version later.
jakebailey commentedon May 16, 2023
I wrapped up the transformer stuff into a concrete-ish issue on #54276.
ssalbdivad commentedon May 17, 2023
In light of what Ryan Cavanaugh (@RyanCavanaugh) and Bruce Pascoe (@fatcerberus) mentioned, I think a more concrete way to say this would've been that I think that a final decision should be made on syntax for both call-site and declaration-site inferred parameters before either is added to the language.
That said, I do think we have a few promising options for each, so I do hope to see one of them in a nightly build in the not too distant future🙏