Microsoft/TypeScript

Type parameter not usable as type argument in identical type; union in constraint becomes intersection

Open

#60,892 opened on Dec 31, 2024

View on GitHub
 (1 comment) (0 reactions) (0 assignees)TypeScript (6,726 forks)batch import
BugDomain: Indexed Access TypesHelp Wanted

Repository metrics

Stars
 (48,455 stars)
PR merge metrics
 (Avg merge 6d 17h) (9 merged PRs in 30d)

Description

🔎 Search Terms

indexed access, constraints, generic, unions, ts2344

🕗 Version & Regression Information

  • This changed between versions 3.3 and 3.5 (likely #30769)

⏯ Playground Link

Playground link

💻 Code

interface Foo<T extends { x: string }, U extends (T | { x: "a" })['x']> {
    z: Foo<T, U> // error!
    //        ~ Type 'U' does not satisfy the constraint 'T["x"] & "a"'. 🙃
}

🙁 Actual behavior

The U type parameter is rejected as a type argument with a TS2344 error about how it doesn't satisfy the constraint. The constraint seems to have shifted from a union to an intersection, even though it comes from an identical place.

🙂 Expected behavior

The U type parameter should be accepted as a type argument.

Additional information about the issue

Distilled from SO question.

I expect this is a consequence of #30769 as per https://github.com/microsoft/TypeScript/issues/31731#issuecomment-498465358, but it is at least somewhat surprising that this should happen when the types involved are identical. One could rewrite the constraint to U extends T["x"] | "a", of course, but this is distilled from the above SO question which is presumably distilled from some use case. What's happening here, exactly, and is it intended, a design limitation, or a bona fide bug?

Contributor guide