-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Exponential compilation slowdown with property accessors and conditional types #29350
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
Comments
I have continued investigating and I believe the issue is related to a combination of:
I have reduced the problem slightly, ignoring the export type PropResult<A, B, P> =
| Get<A, B, P>
| MaybeGet<A, B, P>
| Selector<A, B, P>
| MaybeSelector<A, B, P>
| Converter<A, B, P>
| MaybeConverter<A, B, P>
export type PropOverloads<A, B, P extends {}> = {
<K1 extends keyof B>(key: K1)
: PropResult<A, B[K1], P>
<K1 extends keyof B, K2 extends keyof B[K1]>(key: K1, k2: K2)
: PropResult<A, B[K1][K2], P>
<K1 extends keyof B, K2 extends keyof B[K1], K3 extends keyof B[K1][K2]>(key: K1, k2: K2, k3: K3)
: PropResult<A, B[K1][K2][K3], P>
<K1 extends keyof B, K2 extends keyof B[K1], K3 extends keyof B[K1][K2], K4 extends keyof B[K1][K2][K3]>(key: K1, k2: K2, k3: K3, k4: K4)
: PropResult<A, B[K1][K2][K3][K4], P>
}
However, when you replace the export type PropResult<A, B, P> =
| Get<A, B, {}>
| MaybeGet<A, B, {}>
| Selector<A, B, P>
| MaybeSelector<A, B, P>
| Converter<A, B, P>
| MaybeConverter<A, B, P>
export type PropOverloads<A, B, P extends {}> = {
<K1 extends keyof B>(key: K1)
: PropResult<A, B[K1], P>
<K1 extends keyof B, K2 extends keyof B[K1]>(key: K1, k2: K2)
: PropResult<A, B[K1][K2], P>
<K1 extends keyof B, K2 extends keyof B[K1], K3 extends keyof B[K1][K2]>(key: K1, k2: K2, k3: K3)
: PropResult<A, B[K1][K2][K3], P>
<K1 extends keyof B, K2 extends keyof B[K1], K3 extends keyof B[K1][K2], K4 extends keyof B[K1][K2][K3]>(key: K1, k2: K2, k3: K3, k4: K4)
: PropResult<A, B[K1][K2][K3][K4], P>
}
What is special about export type GetSignature<A, B, Params extends {}> =
{} extends Params
? (a: A) => B
: (a: A, params: Params) => B
export type Get<A, B, Params extends {} = {}> = GetSignature<A, B, Params> & {
...
} |
@weswigham do you think you'll be able to assign someone to help out with this? |
Further investigation reveals that removing the ...
ifDefined: IfDefinedOverloads<Dimensionality.Single, Structure.Get, A, B, Params>
...
export type IfOptional<T, U> = undefined extends T ? U : null extends T ? U : never
export type IfDefinedOverloads<D extends Dimensionality, S extends Structure, A, B, Params extends {}> = IfOptional<B, {
(): Composable.ComposeResult<A, Exclude<B, null | undefined>, Params, D, Dimensionality.Maybe, S, Structure.Convert>
(defaultValue: B): Composable.ComposeResult<A, Exclude<B, null | undefined>, Params, D, Dimensionality.Single, S, Structure.Convert>
}> It's specifically the I guess what is happening is that the compiler expands the indexed accessor and this creates some combinatorial explosion with the multiple conditional types? |
Apologies, I have had to break from the template in order to describe this issue since it is not easily reproduced in a simple demo.
TypeScript Version: 3.0.3, 3.2.2, 3.3.0-dev.20190110
Search Terms: compilation performance, generic property accessor, conditional types
Code
So far in investigating this issue I have identified this code block as the culprit, due to this commit
"Supporting" code:
Expected behavior: A compilation time of ~3 seconds, akin to the previous commit
Actual behavior: A compilation time of ~80 seconds
Related Issues: none that I could find
Output of
tsc --diagnostics
Before this change, in the previous commit:
After this change:
Without the 4-argument overload:
With only the 1- and 2-argument overloads:
With only the 1-argument overload:
I am not really sure how to narrow this down to a particular problem or debug the compilation time; I only notice that the number of types and symbols increases hugely with just a single method interface
The text was updated successfully, but these errors were encountered: