Skip to content

Hex String - Expression produces a union type that is too complex to represent. #43388

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

Closed
jrista opened this issue Mar 26, 2021 · 5 comments
Closed
Labels
Duplicate An existing issue was already created

Comments

@jrista
Copy link

jrista commented Mar 26, 2021

Bug Report

I recently ran into this type error. I understand that there are cases where reducing the complexity of a union can be challenging, however in this particular case...I do wonder if it actually is really too complex, given the repetitive nature of the type.

Using the new TS v4 Template Literal types, I have tried to create a type for a MongoDB ObjectId. I started out quite basic:

type Hex =  '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | 'a' | 'b' | 'c' | 'd' | 'e' | 'f';

export type ObjectId = `${Hex}${Hex}${Hex}${Hex}${Hex}${Hex}${Hex}${Hex}${Hex}${Hex}${Hex}${Hex}${Hex}${Hex}${Hex}${Hex}${Hex}${Hex}${Hex}${Hex}${Hex}${Hex}${Hex}${Hex}`;

This spit back the too complex to represent error. I then wondered if I transitioned some of the complexity from the template literal type to the union, if that might make a difference:

type Hex =
  '00' | '01' | '02' | '03' | '04' | '05' | '06' | '07' | '08' | '09' | '0a' | '0b' | '0c' | '0d' | '0e' | '0f' |
  '10' | '11' | '12' | '13' | '14' | '15' | '16' | '17' | '18' | '19' | '1a' | '1b' | '1c' | '1d' | '1e' | '1f' |
  '20' | '21' | '22' | '23' | '24' | '25' | '26' | '27' | '28' | '29' | '2a' | '2b' | '2c' | '2d' | '2e' | '2f' |
  '30' | '31' | '32' | '33' | '34' | '35' | '36' | '37' | '38' | '39' | '3a' | '3b' | '3c' | '3d' | '3e' | '3f' |
  '40' | '41' | '42' | '43' | '44' | '45' | '46' | '47' | '48' | '49' | '4a' | '4b' | '4c' | '4d' | '4e' | '4f' |
  '50' | '51' | '52' | '53' | '54' | '55' | '56' | '57' | '58' | '59' | '5a' | '5b' | '5c' | '5d' | '5e' | '5f' |
  '60' | '61' | '62' | '63' | '64' | '65' | '66' | '67' | '68' | '69' | '6a' | '6b' | '6c' | '6d' | '6e' | '6f' |
  '70' | '71' | '72' | '73' | '74' | '75' | '76' | '77' | '78' | '79' | '7a' | '7b' | '7c' | '7d' | '7e' | '7f' |
  '80' | '81' | '82' | '83' | '84' | '85' | '86' | '87' | '88' | '89' | '8a' | '8b' | '8c' | '8d' | '8e' | '8f' |
  '90' | '91' | '92' | '93' | '94' | '95' | '96' | '97' | '98' | '99' | '9a' | '9b' | '9c' | '9d' | '9e' | '9f' |
  'a0' | 'a1' | 'a2' | 'a3' | 'a4' | 'a5' | 'a6' | 'a7' | 'a8' | 'a9' | 'aa' | 'ab' | 'ac' | 'ad' | 'ae' | 'af' |
  'b0' | 'b1' | 'b2' | 'b3' | 'b4' | 'b5' | 'b6' | 'b7' | 'b8' | 'b9' | 'ba' | 'bb' | 'bc' | 'bd' | 'be' | 'bf' |
  'c0' | 'c1' | 'c2' | 'c3' | 'c4' | 'c5' | 'c6' | 'c7' | 'c8' | 'c9' | 'ca' | 'cb' | 'cc' | 'cd' | 'ce' | 'cf' |
  'd0' | 'd1' | 'd2' | 'd3' | 'd4' | 'd5' | 'd6' | 'd7' | 'd8' | 'd9' | 'da' | 'db' | 'dc' | 'dd' | 'de' | 'df' |
  'e0' | 'e1' | 'e2' | 'e3' | 'e4' | 'e5' | 'e6' | 'e7' | 'e8' | 'e9' | 'ea' | 'eb' | 'ec' | 'ed' | 'ee' | 'ef' |
  'f0' | 'f1' | 'f2' | 'f3' | 'f4' | 'f5' | 'f6' | 'f7' | 'f8' | 'f9' | 'fa' | 'fb' | 'fc' | 'fd' | 'fe' | 'ff' ;

export type ObjectId = `${Hex}${Hex}${Hex}${Hex}${Hex}${Hex}${Hex}${Hex}${Hex}${Hex}${Hex}${Hex}`;

Sadly, this did not help. While TypeScript did not complain about the Hex union, it still complained about the template literal. The highly repetitive nature of the type makes me think it should be possible to reduce the complexity to something that actually could be represented.

🔎 Search Terms

"Expression produces a union type that is too complex to represent."

🕗 Version & Regression Information

  • This occurs in 4.x

⏯ Playground Link

ObjectId Playground

💻 Code

type Hex =  '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | 'a' | 'b' | 'c' | 'd' | 'e' | 'f';

export type ObjectId = `${Hex}${Hex}${Hex}${Hex}${Hex}${Hex}${Hex}${Hex}${Hex}${Hex}${Hex}${Hex}${Hex}${Hex}${Hex}${Hex}${Hex}${Hex}${Hex}${Hex}${Hex}${Hex}${Hex}${Hex}`;

🙁 Actual behavior

TypeScript was unable to represent the ObjectId type due to a union that was too complex.

🙂 Expected behavior

TypeScript should be able to handle initially complex unions if the parts of that union are very repetitive... (?)

@jrista
Copy link
Author

jrista commented Mar 26, 2021

Another example, just tried: A 16-digit credit card number:

type Digit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9';
export type CardNumber = `${Digit}${Digit}${Digit}${Digit}${Digit}${Digit}${Digit}${Digit}${Digit}${Digit}${Digit}${Digit}${Digit}${Digit}${Digit}${Digit}`;

Interestingly, if I shorten it to this:

export type CardNumber = `${Digit}${Digit}${Digit}${Digit}`;

It does not complain.

@MartinJohns
Copy link
Contributor

MartinJohns commented Mar 26, 2021

Duplicate of #43283 / #40803 and many others. Another relevant issue that is essentially the same as yours: #43335

This changed between versions 3.x and 4.x

Gvien that this feature didn't even exist in TypeScript 3.x, I'm really not sure why you would say this changed between these versions.

@jrista
Copy link
Author

jrista commented Mar 26, 2021

I wouldn't say it is a duplicate of the first two. They both use more complex type structures. I still think there is a legitimate question in why it is not possible to reduce such a repetitive type to something that can be properly represented.

@MartinJohns
Copy link
Contributor

I still think there is a legitimate question in why it is not possible to reduce such a repetitive type to something that can be properly represented.

That's probably why the TypeScript team didn't close #43335, which definitely is a duplicate of this. Right now it's not working because the feature was simply never intended for something like this, that's why it builds up on union types which have the hard limit.

@RyanCavanaugh RyanCavanaugh added the Duplicate An existing issue was already created label Mar 26, 2021
@typescript-bot
Copy link
Collaborator

This issue has been marked as a 'Duplicate' and has seen no recent activity. It has been automatically closed for house-keeping purposes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

4 participants