Skip to content

Inference for contravariant positions in second argument of conditional type results in arbitrary union supertype #38039

Closed
@reverofevil

Description

@reverofevil

TypeScript Version: 3.8.3 (Nightly is broken at the moment)

Search Terms:
distributive conditional types over intersection

Code

type X = (
    ((x: { a: 1 }) => 0) & ((x: { b: 2 }) => 0)
) extends (a: infer T) => any ? T : never;
type Y = (
    ((x: { b: 2 }) => 0) & ((x: { a: 1 }) => 0)
) extends (a: infer T) => any ? T : never;
type XY = X extends Y ? Y extends X ? true : false : false;

type A = (
    ((x: { a: 1 }) => 0) | ((x: { b: 2 }) => 0)
) extends (a: infer T) => any ? T : never; 
type B = (
    ((x: { b: 2 }) => 0) | ((x: { a: 1 }) => 0)
) extends (a: infer T) => any ? T : never;
type AB = A extends B ? B extends A ? true : false : false;

Expected behavior:
XY and AB both true, i.e. condition types distribute over intersections the same way as over unions.

Actual behavior:
XY is false. Type checker picks the last term of intersection.

Playground Link:
Playground Link.

Related Issues:
https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#distributive-conditional-types

Metadata

Metadata

Assignees

No one assigned

    Labels

    Working as IntendedThe behavior described is the intended behavior; this is not a bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions