-
Notifications
You must be signed in to change notification settings - Fork 13k
Closed
Labels
Design NotesNotes from our design meetingsNotes from our design meetings
Description
Smarter Literal/Subtype Reduction
- Imagine
EnumA
andEnumB
which each have 1000 members. - If you have an array like
[EnumA.Member1, EnumB.Member1, someObject]
, then we'll try to do subtype reduction. - Each enum is technically a union, with 1000 literal type members.
- Subtype reduction is O(n2), so when we try to reduce each enum, that can end up being expensive! We have a heuristic to avoid doing this work by checking up-front if we're going to do a lot of work.
- However, in this PR, we always start out by doing a literal type reduction pass (a pass which is way cheaper than general subtype reduction), and then do full subtype reduction.
- We always had a literal type reduction pass, but now we always apply it in the presence of any literal types (not just all-literal types).
- We also had this other special code to handle enums before; seems like we were able to remove them.
- The code got smaller from this change! 🎉
- Some...breaks.
- We used to keep
void | undefined
- now we reduce it toundefined
. - A change where we now do not reduce primitives and object types that have members in common..
- For example,
[someString, { toString(): string { return "hi" } }]
doesn't reduce to just the object type.
- For example,
- We used to keep
- Does it make sense that
undefined
is reduced tovoid
? Isn't it the other way around?- We've always had
void
being a supertype ofundefined
.
- We've always had
- Users try to cast to
unknown[]
orany[]
or whatever, but it doesn't stop the complex computation. Could we peek at that?- Potentially - could just do a single assignability check to
Exploding Template String Types
`${theme.colors.grey} ${theme.colors.grey} ${theme.colors.white}`
declare var a: "a" | "whole" | "bunch" | "of" | ... | "strings";
const t = `${a} ${a} ${a}`;
-
Expands out to a very big union type.
-
If the union is too big, it can be too complex.
-
It used to be that you had to opt into template literal types with
as const
on template strings - now you're sort of always thrown into it. -
Two proposals
- One is "this thing is too big" and give a better error message, and
- make it so that
as string
allows you to opt out.
-
Do we have any tests for perf?
- Relatively new feature.
- Well we know this is strictly never going to be faster.
-
Try to find some project that uses template strings to see what sort of regressions they have.
- Artsy has some, we can ping them!
-
Also maybe provide a quick fix.*
-
Feels like the usual expectation is "give me a reasonable type, and I'll use
as const
unless I opt-in." -
Can convince ourselves of either direction.
-
Thing that's odd about not doing this work
const x = `somestring`; // this is a literal type const str = "string; const x = `some${str}`; // this is not? fishy.
-
We really should try to avoid doing the full type computation if you're contextually typed, it happens all the time.
Metadata
Metadata
Assignees
Labels
Design NotesNotes from our design meetingsNotes from our design meetings