microsoft / microsoft/TypeScript
Bug: Circular references not allowed for template literal types
Open
Nobody has claimed this yet.
Awaiting More Feedback
Suggestion
- Dominant language
- Go
- Stars
- 111k
- Forks
- 14.4k
- Avg merge
- 1d 19h
- Merged PRs (30d)
- 117
Description
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.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the linked TypeScript Playground and the reduced recursive tuple and template-literal examples in the issue. Compare how recursive tuple aliases are accepted with how the template literal alias is rejected; done means the OneOrMoreStr examples type-check without the circular-reference errors.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100