Skip to content
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

Covariant generic parameters fail unification #61503

Open
feedab1e opened this issue Mar 28, 2025 Β· 0 comments
Open

Covariant generic parameters fail unification #61503

feedab1e opened this issue Mar 28, 2025 Β· 0 comments
Labels
Bug A bug in TypeScript Help Wanted You can do this
Milestone

Comments

@feedab1e
Copy link

feedab1e commented Mar 28, 2025 β€’

πŸ”Ž Search Terms

"contravariant", "unification"

πŸ•— Version & Regression Information

  • This changed between versions 3.3.3 and 3.5.1

⏯ Playground Link

https://www.typescriptlang.org/play/?jsx=0#code/MYewdgzgLgBKZQE4EMBuzEEtkJgXhgAoBKfAPhgG8AoGOcaegWwCNMwBTfGAHgGEoADzKEA+gEYAXEWCSBg0ngpgArgBs1AGhiiATNMKz5i5erXEDJmPPJErKsABMOAM3YdHMZBC9gAngDc1LT0kLBqHBAQovDQWJyeBPwwHIJQHE4+lBFgAOZQABaSqqwciAC+IrLWFjCqGrb1akF0sbBMIIgcMQxI7om8fClpGY5ZOflFJSxl2sAFGHwgzgCCUGLFKqWIFtNllYbSfLVNjWYtoYzp0OLcoKzuhBFRPWHxHtodXa9x-cQXbRg1ygujuIAenEIX26bXejm0z2isL+AN6MEQ3GB4hIQXKwUBoHQWBwsAIJFsNFaaPubE43H4QhEEkstnk2j0LKU1iEtRsXIczjcCS8PhwgWCVLCMERPz6wqSQ1S6UyVAmhU22wOvNsAtc-RFvnFksY0NlcPpipGKuyGUmGpmiDmC0QS1W61E9rKuy2Dq1Rx1Tj1wu8htRUqxYIhHCekSRvThn06MPjKJCgOBoIINMepuRCQRsbNqfKQA

πŸ’» Code

const contravariant = () => {
  const combine = <Ctx>(_1: (c:Ctx) => null, _2: (c:Ctx) => null): () => Ctx => () => undefined as any;

  const less_constrined = <C extends {length:number}>(c: C): null => null;
  const more_constrined = <C extends {length:number, charCodeAt(_:number):number}>(c: C): null => null;
  const test1 = combine(less_constrined, more_constrined);
  const test2 = combine(more_constrined, less_constrined);
}

const covariant = () => {
  const combine = <Ctx>(_1: () => Ctx, _2: () => Ctx): Ctx => undefined as any;

  const less_constrined = <C extends {length:number}>(): C => undefined as any;
  const more_constrined = <C extends {length:number, charCodeAt(_:number):number}>(): C => undefined as any;
  const test1 = combine(less_constrined, more_constrined);
  const test2 = combine(more_constrined, less_constrined);
}

πŸ™ Actual behavior

In the contravariant example the type is inferred from the first argument, so test1 fails to typecheck, despite both test1 and test2 sharing the same argument types, just reversed. This is also different from the covariant case where types are properly unified in both test1 and test2

πŸ™‚ Expected behavior

The behaviour for the covariant and contravariant case should match, so test1 should be inferred as
<C extends { length: number; charCodeAt(_: number): number; }>() => C

Additional information about the issue

No response

@RyanCavanaugh RyanCavanaugh added Bug A bug in TypeScript Help Wanted You can do this labels Mar 28, 2025
@RyanCavanaugh RyanCavanaugh added this to the Backlog milestone Mar 28, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript Help Wanted You can do this
Projects
None yet
Development

No branches or pull requests

2 participants