microsoft / microsoft/TypeScript

Expression produces a union type that is too complex to represent

Open
#53,234 17 comments 2 reactions 1 assignee View on GitHub

@gabritto is already working on this.

Since Mar 30, 2023.

Has Repro Needs Investigation
Dominant language
Go
Stars
111k
Forks
14.4k
Avg merge
1d 19h
Merged PRs (30d)
117

Description

Bug Report

🔎 Search Terms

"Expression produces a union type that is too complex to represent"
(found #33130 which seems unrelated as it has been fixed)

🕗 Version & Regression Information
  • Present from 4.1.5 to 5.0.2 in playground.
⏯ Playground Link

Example in Playground

💻 Code
function computed<N extends keyof Longhands>(
  property: Longhands[N][1],
  specified: Longhands[N][0]
) {
  // error happens on this line
  property.compute(specified);
}

interface Property<T> {
  compute: (value: T) => T;
}

type Wrapper<T> = [T, Property<T>];

interface Longhands {
  "font-family": Wrapper<Family>;
  "font-size": Wrapper<Size>;
  "font-stretch": Wrapper<Stretch>;
  "font-variant-caps": Wrapper<Caps>;
  "font-variant-east-asian": Wrapper<EastAsian>;
  "font-variant-ligatures": Wrapper<Ligatures>;
  "font-variant-numeric": Wrapper<Numeric>;
  "font-variant-position": Wrapper<Position>;
  "font-weight": Wrapper<Weight>;
}

class Keyword<K extends string> {
  keyword: K;
  constructor(keyword: K) {
    this.keyword = keyword;
  }
}

type Family = Keyword<"serif">;
type Size = Keyword<"length">;
type Stretch =
  | Keyword<"percentage">
  | Keyword<"ultra-condensed">
  | Keyword<"extra-condensed">
  | Keyword<"condensed">
  | Keyword<"semi-condensed">
  | Keyword<"normal">
  | Keyword<"semi-expanded">
  | Keyword<"expanded">
  | Keyword<"extra-expanded">
  | Keyword<"ultra-expanded">;
type Caps = Keyword<"normal">;
type EastAsian =
  | Keyword<"normal">
  | Keyword<"jis78">
  | Keyword<"jis83">
  | Keyword<"jis90">
  | Keyword<"jis04">
  | Keyword<"simplified">
  | Keyword<"traditional">
  | Keyword<"proportional-width">
  | Keyword<"full-width">
  | Keyword<"ruby">;
type Ligatures =
  | Keyword<"none">
  | Keyword<"normal">
  | Keyword<"common-ligatures">
  | Keyword<"no-common-ligatures">
  | Keyword<"discretionary-ligatures">
  | Keyword<"no-discretionary-ligatures">
  | Keyword<"historical-ligatures">
  | Keyword<"no-historical-ligatures">
  | Keyword<"contextual">
  | Keyword<"no-contextual">;
type Numeric =
  | Keyword<"normal">
  | Keyword<"lining-nums">
  | Keyword<"oldstyle-nums">
  | Keyword<"proportional-nums">
  | Keyword<"tabular-nums">
  | Keyword<"diagonal-fractions">
  | Keyword<"stacked-fractions">
  | Keyword<"ordinal">
  | Keyword<"slashed-zero">;
type Position = Keyword<"normal"> | Keyword<"sub"> | Keyword<"super">;
type Weight =
  | Keyword<"number">
  | Keyword<"normal">
  | Keyword<"bold">
  | Keyword<"bolder">
  | Keyword<"lighter">;

Note: interestingly, I detected the error in the much more complex real code of Alfa where it only triggers in TS 4.9.3, but not in 4.8.4 🤔 I am not sure which simplification happens in my real code to keep the union smaller…

🙁 Actual behavior

The code produces the error:

Expression produces a union type that is too complex to represent

🙂 Expected behavior

The union should be around 50 items big, far below the limit.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.