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

Type inference for union of arrays broken #27337

Closed
ulrichb opened this issue Sep 25, 2018 · 4 comments
Closed

Type inference for union of arrays broken #27337

ulrichb opened this issue Sep 25, 2018 · 4 comments
Assignees
Labels
Bug A bug in TypeScript Fixed A PR has been merged for this issue

Comments

@ulrichb
Copy link

ulrichb commented Sep 25, 2018

TypeScript Version: Version 3.1.0-dev.20180925

Search Terms: array this context type compatibility assignability

Code

interface Array<T> {
    equalsShallow<T>(this: ReadonlyArray<T>, other: ReadonlyArray<T>): boolean;
}

type ExtractArrayType<TArray> = TArray extends Array<infer T> ? T : never;

[
    { a: ["x"], b: [] },
    { a: [], b: ["x"] },
    { a: ["x", 2], b: ["x", 2] },
    { a: ["1"], b: [1] },
    { a: [1], b: ["1"] },
    { a: [null], b: [undefined] },
    { a: [undefined], b: [null] },
    { a: [{}], b: [{}] },
].forEach(({ a, b }) => {

    // Compiles:
    const assignedA: typeof a = b;
    const assignedB: typeof b = a;

    // Compiles (prove that ReadonlyArray<>-types are compatible):
    const assignedAReadonly: ReadonlyArray<ExtractArrayType<typeof a>> = b;
    const assignedBReadonly: ReadonlyArray<ExtractArrayType<typeof b>> = a;

    // error TS2684: The 'this' context of type '(string | number)[] | null[] | undefined[] | {}[]'
    // is not assignable to method's 'this' of type 'ReadonlyArray<string | number>':
    a.equalsShallow(b);
});

Works in TS 3.0.

Note that the error disappears when changing equalsShallow() to equalsShallow<T>(this: Array<T>, other: Array<T>): boolean.

Further note that the error disappears when extracting a type for a and b (instead of using the literal type inference).

Expected behavior: No compile error

Actual behavior: Compile error, see snippet

Playground Link: Link (no error because it's TS 3.0)

@ghost
Copy link

ghost commented Sep 25, 2018

Simplified repro:

declare function f<T>(a: ReadonlyArray<T>, other: ReadonlyArray<T>): boolean;
declare const a: number[] | string[];
f(a, a);

@ghost ghost added the Bug A bug in TypeScript label Sep 25, 2018
@ghost ghost changed the title Type error for this context although types are assignable (broke in 3.1) Type inference for union of arrays broken Sep 25, 2018
@RyanCavanaugh RyanCavanaugh added this to the TypeScript 3.2 milestone Sep 25, 2018
@ahejlsberg ahejlsberg assigned ahejlsberg and unassigned weswigham Sep 25, 2018
@ahejlsberg
Copy link
Member

This appears to be an effect of #27028 which I merged yesterday. The release-3.1 branch is not affected.

@ulrichb
Copy link
Author

ulrichb commented Sep 26, 2018

Okay, If I understood it correctly, the 3.2 feature #27028 was on the 3.1 (@next) channel for short amount of time and introduced this issue => this issue won't arrive in the 3.1 release and therefore is tagged with the 3.2 milestone.

Correct?

@ahejlsberg
Copy link
Member

@andy-ms Your simplified repro above is already an error in 3.0. This is a correct simplified repro:

declare function f<T>(a: ReadonlyArray<T>, other: ReadonlyArray<T>): boolean;
declare const a: number[] | {}[];
f(a, a);

@ulrichb The upcoming 3.1 release is in the release-3.1 branch, so master is technically the 3.2 release now (and has been for several days). We just hadn't bumped the version tag (but that's done now).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript Fixed A PR has been merged for this issue
Projects
None yet
Development

No branches or pull requests

4 participants