Skip to content

Poor conditional type performance with large string literal union types #47481

Closed
@phulin

Description

@phulin

Bug Report

The TypeScript compiler has poor performance when compiling conditional types involving large string literal unions. In particular, performance appears to be multilinear in the size of the unions involved. The example below takes 19 seconds to compile on my (recent) laptop, with two 10,000 string literal union types. A 5,000 x 5,000 example takes 4.5 seconds, a 10,000 x 5,000 example 9 seconds, and a 15,000 x 10,000 example 27 seconds, suggesting the asymptotic performance I indicated.

I discovered this issue while attempting to implement strong typing on requests to a key-value store in a project. The values in the store have different types that are static, but the store is large enough that using types like the example below leads to what is, for me, unacceptably slow compile times (which are then reflected in slow VS Code Intellisense updates).

I imagine this may be a fundamental algorithmic limitation, but I don't know enough about TS's inner workings to know.

This may be related to #29350.

Thanks to all TS contributors - hope this report helps.

🔎 Search Terms

union conditional type poor performance slow multilinear quadratic

🕗 Version & Regression Information

Observed on multiple versions, including today's next. I have not seen a version with good performance in this case.

⏯ Playground Link

Unfortunately, playground screeches to a halt with the full 10,000 x 10,000 test case. Here is a 1,000 x 1,000 example instead:

Playground link with relevant code

Test case repository

💻 Code

export type NumericProperty = "n1" | "n2" | /* snip */ "n10000";
export type StringProperty = "s1" | "s2" | /* snip */ "s10000";
export type KnownProperty =
  | NumericProperty
  | StringProperty

type PropertyValue<
  Property,
> = Property extends NumericProperty
  ? number
  : Property extends StringProperty
  ? string : null;

export function useProperty<Property extends KnownProperty>(
  default_: PropertyValue<Property>,
): PropertyValue<Property> {
  return default_;
}

Metadata

Metadata

Assignees

Labels

Needs InvestigationThis issue needs a team member to investigate its status.RescheduledThis issue was previously scheduled to an earlier milestone

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions