microsoft / microsoft/TypeScript
False positive for Circular dependency error
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 111k
- Forks
- 14.4k
- Avg merge
- 1d 19h
- Merged PRs (30d)
- 117
Description
Bug Report
Hello. First of all want to express my love to TypeScript and admit of all work you did for the best typing system I've ever known.
I believe I found a bug where three points are touched: type inference, recursive types and variadic params. The bug doesn't happen when you take off any of this points. I put the reproduction code below.
I believe that it's a bug because the main recursive feature works fine for composite that has slightly complicated signature. Also, I can make failing working by making a union with a dummy type, so it's
failing: AComponent<[ARows | 'never']>
The bug doesn't happen when I have the direct components type without infering:
type AComponentTypes = {
simple: [string],
composite: [string, ARows]
failing: [ARows]
}
The bug doesn't happen when I don't use variadic types:
type ARowUnion<U> = U extends keyof AComponents ? [U, AArgument<AComponents[U]>] : never
Is there any other workarounds besides defining a unionARows | 'never' ?
I spent about 4 hours struggling with this so I hope this is a helpful finding. Thank you
🔎 Search Terms
typescript, generic types, variadic types, composition, recursion, self reference, mapped types, false positive
🕗 Version & Regression Information
- This is the behavior in every version I tried, and I reviewed the FAQ for entries about
- I was unable to test this on prior versions because variadic types were not implemented.
- There is no working version. 4.0.5. still has the problem, but 3.9.7 seems not supporting variadic types.
⏯ Playground Link
Playground link with relevant code
💻 Code
type AComponents = {
simple: AComponent<[string]>,
composite: AComponent<[string, ARows]>
failing: AComponent<[ARows]>
}
type AComponent<T extends unknown[]> = (args: T) => void
type AArgument<T> = T extends AComponent<infer V> ? V : never
type ARowUnion<U> = U extends keyof AComponents ? [U, ...AArgument<AComponents[U]>] : never
type ARow = ARowUnion<keyof AComponents>
type ARows = ARow[]
const rows: ARow[] = [
['simple', 'Hello world'],
['composite', 'my param', [
['simple', 'Hello world'],
]],
['failing', [
['simple', 'Hello world'],
]]
]
🙁 Actual behavior
Type alias 'ARow' circularly references itself.
Type arguments for 'Array' circularly reference themselves.
🙂 Expected behavior
There is no errors for the types definitions, both failing and component types are valid and allows recursive structures.
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 reproduce the circular-reference diagnostics using the provided recursive, inferred, variadic tuple types. Compare the failing definitions with the listed working variants, then trace the relevant type-checking behavior. Done means the valid recursive structure no longer reports circular-reference errors and the regression is covered by an appropriate compiler test.
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
- 35/100