question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Bug: Circular references not allowed for template literal types

See original GitHub issue

Bug Report

🔎 Search Terms

  • circularly, template literal

Related issues: #43335.

🕗 Version & Regression Information

  • This changed between versions 4.0.5 and 4.1.5 (different bug before)

⏯ Playground Link

Playground link with relevant code

💻 Code

// you can have circular references in tuple types
type OneOrMoreArr0<C> = C | [C, ...OneOrMoreArr0<C>[]];
// note that
//
// type OneOrMoreArr0<C> = C | [C, OneOrMoreArr0<C>];
//
// is also valid
type OneOrMoreArr<C> = Exclude<OneOrMoreArr0<C>, C>;

const noEmptyArr: [] extends OneOrMoreArr<'*'> ? false : true = true;

const x1: OneOrMoreArr<'*'> = ['*'];
const x2: OneOrMoreArr<'*'> = ['*', '*'];
const x3: OneOrMoreArr<'*'> = ['*', '*', '*']

// but when you try and do the same thing with template literal types, you get an error
//
// "Type alias 'OneOrMoreStr0' circularly references itself."
//
// "Type 'OneOrMoreStr0' is not generic."
type OneOrMoreStr0<C extends string> = C | `${C}${OneOrMoreStr0<C>}`

// we should be able to do the above, and then have e.g.,
//
// const y1: OneOrMoreStr<'*'> = '*';
// const y2: OneOrMoreStr<'*'> = '**';
// const y3: OneOrMoreStr<'*'> = '***';


// if 'C' is the empty string, the above just reduces to:
//
// OneOrMoreStr0<''> = '';
//
// otherwise the same logic as with `OneOrMoreArr0` should apply

🙁 Actual behavior

You get the error:

    Type alias 'OneOrMoreStr0' circularly references itself.
    Type 'OneOrMoreStr0' is not generic.

🙂 Expected behavior

This should type check like with the tuple example - it’s the same principle, just with template literals.

Issue Analytics

  • State:open
  • Created 2 years ago
  • Reactions:7
  • Comments:11 (4 by maintainers)

github_iconTop GitHub Comments

2reactions
andrewbranchcommented, Jul 20, 2021

I’m honestly not enough of an expert on how we deal with deferred recursive types to be 100% confident about how difficult this would be and what the biggest challenges would be, but I’m familiar enough to have an intuition that it would be complicated. Even if I were wrong about that, I think we’d want to see compelling use cases for why we should add this kind of complexity. Template literal types were created in large part to support mapped type as clauses, which have super compelling uses, like describing the relationship between an object like { foo: string } and { getFoo(): string, setFoo(foo: string): void }. I don’t think a super-fine-grained type-space string validator is as compelling as that, but that’s why issues like this one are Awaiting More Feedback.

1reaction
andrewbranchcommented, Jul 12, 2021

Yes 😄

Read more comments on GitHub >

github_iconTop Results From Across the Web

Typescript template literal types circular constraint
I cannot reference P in the template literal since it creates a circular constraint. Another way might be to reference "original" P, but...
Read more >
Invalid template errors - Azure Resource Manager
This article describes how to resolve invalid template errors for Bicep files and Azure Resource Manager templates (ARM templates). The error ...
Read more >
Circular reference in Excel: how to find, enable, use, or remove
If circular references are not allowed in your Excel (and they are turned off by default), you will see an error message we've...
Read more >
TypeError: cyclic object value - JavaScript - MDN Web Docs
To serialize circular references you can use a library that supports them (e.g. cycle.js) or implement a solution by yourself, ...
Read more >
References - FHIR v5.0.0-snapshot3
Resources contain two types of references to other resources: ... identifier · Σ, 0..1, Identifier, Logical reference, when literal reference is not known....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found