Closed
Description
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)