From d1cfec592a11a87d4025c9107c0725f89dc6b721 Mon Sep 17 00:00:00 2001 From: craigphicks <13205732+craigphicks@users.noreply.github.com> Date: Sun, 12 Nov 2023 23:10:57 +0000 Subject: [PATCH 1/6] original checker and new tests/result original source and new tests/results --- .../arrayFilterBooleanExternalOverload1.js | 34 ++++++ ...rrayFilterBooleanExternalOverload1.symbols | 38 +++++++ .../arrayFilterBooleanExternalOverload1.types | 54 +++++++++ ...yFilterBooleanExternalOverload2.errors.txt | 38 +++++++ .../arrayFilterBooleanExternalOverload2.js | 60 ++++++++++ ...rrayFilterBooleanExternalOverload2.symbols | 67 ++++++++++++ .../arrayFilterBooleanExternalOverload2.types | 81 ++++++++++++++ .../arrayFilterBooleanExternalOverload3.js | 47 ++++++++ ...rrayFilterBooleanExternalOverload3.symbols | 59 ++++++++++ .../arrayFilterBooleanExternalOverload3.types | 71 ++++++++++++ ...yFilterBooleanExternalOverload4.errors.txt | 59 ++++++++++ .../arrayFilterBooleanExternalOverload4.js | 54 +++++++++ ...rrayFilterBooleanExternalOverload4.symbols | 95 ++++++++++++++++ .../arrayFilterBooleanExternalOverload4.types | 103 ++++++++++++++++++ .../arrayFilterBooleanExternalOverload1.ts | 19 ++++ .../arrayFilterBooleanExternalOverload2.ts | 31 ++++++ .../arrayFilterBooleanExternalOverload3.ts | 24 ++++ .../arrayFilterBooleanExternalOverload4.ts | 27 +++++ 18 files changed, 961 insertions(+) create mode 100644 tests/baselines/reference/arrayFilterBooleanExternalOverload1.js create mode 100644 tests/baselines/reference/arrayFilterBooleanExternalOverload1.symbols create mode 100644 tests/baselines/reference/arrayFilterBooleanExternalOverload1.types create mode 100644 tests/baselines/reference/arrayFilterBooleanExternalOverload2.errors.txt create mode 100644 tests/baselines/reference/arrayFilterBooleanExternalOverload2.js create mode 100644 tests/baselines/reference/arrayFilterBooleanExternalOverload2.symbols create mode 100644 tests/baselines/reference/arrayFilterBooleanExternalOverload2.types create mode 100644 tests/baselines/reference/arrayFilterBooleanExternalOverload3.js create mode 100644 tests/baselines/reference/arrayFilterBooleanExternalOverload3.symbols create mode 100644 tests/baselines/reference/arrayFilterBooleanExternalOverload3.types create mode 100644 tests/baselines/reference/arrayFilterBooleanExternalOverload4.errors.txt create mode 100644 tests/baselines/reference/arrayFilterBooleanExternalOverload4.js create mode 100644 tests/baselines/reference/arrayFilterBooleanExternalOverload4.symbols create mode 100644 tests/baselines/reference/arrayFilterBooleanExternalOverload4.types create mode 100644 tests/cases/compiler/arrayFilterBooleanExternalOverload1.ts create mode 100644 tests/cases/compiler/arrayFilterBooleanExternalOverload2.ts create mode 100644 tests/cases/compiler/arrayFilterBooleanExternalOverload3.ts create mode 100644 tests/cases/compiler/arrayFilterBooleanExternalOverload4.ts diff --git a/tests/baselines/reference/arrayFilterBooleanExternalOverload1.js b/tests/baselines/reference/arrayFilterBooleanExternalOverload1.js new file mode 100644 index 0000000000000..f37848ddd1c14 --- /dev/null +++ b/tests/baselines/reference/arrayFilterBooleanExternalOverload1.js @@ -0,0 +1,34 @@ +//// [tests/cases/compiler/arrayFilterBooleanExternalOverload1.ts] //// + +//// [arrayFilterBooleanExternalOverload1.ts] +// #56013 + +// For reference, thise cases work as expected (no errors) when no external BooleanConstrudtor like overload is present +declare const maybe: boolean; +{ + const id = () => (t: T) => !!t; + + const result1 = (maybe ? ['foo', 'bar', undefined] : [1] ).filter(id()); + + result1; + + const result2 = ['foo', 'bar', undefined].filter(id()); // want id() = (t: string) => boolean + + result2; +} + + +//// [arrayFilterBooleanExternalOverload1.js] +"use strict"; +// #56013 +{ + const id = () => (t) => !!t; + const result1 = (maybe ? ['foo', 'bar', undefined] : [1]).filter(id()); + result1; + const result2 = ['foo', 'bar', undefined].filter(id()); // want id() = (t: string) => boolean + result2; +} + + +//// [arrayFilterBooleanExternalOverload1.d.ts] +declare const maybe: boolean; diff --git a/tests/baselines/reference/arrayFilterBooleanExternalOverload1.symbols b/tests/baselines/reference/arrayFilterBooleanExternalOverload1.symbols new file mode 100644 index 0000000000000..ac005eb5eab9f --- /dev/null +++ b/tests/baselines/reference/arrayFilterBooleanExternalOverload1.symbols @@ -0,0 +1,38 @@ +//// [tests/cases/compiler/arrayFilterBooleanExternalOverload1.ts] //// + +=== arrayFilterBooleanExternalOverload1.ts === +// #56013 + +// For reference, thise cases work as expected (no errors) when no external BooleanConstrudtor like overload is present +declare const maybe: boolean; +>maybe : Symbol(maybe, Decl(arrayFilterBooleanExternalOverload1.ts, 3, 13)) +{ + const id = () => (t: T) => !!t; +>id : Symbol(id, Decl(arrayFilterBooleanExternalOverload1.ts, 5, 9)) +>T : Symbol(T, Decl(arrayFilterBooleanExternalOverload1.ts, 5, 16)) +>t : Symbol(t, Decl(arrayFilterBooleanExternalOverload1.ts, 5, 25)) +>T : Symbol(T, Decl(arrayFilterBooleanExternalOverload1.ts, 5, 16)) +>t : Symbol(t, Decl(arrayFilterBooleanExternalOverload1.ts, 5, 25)) + + const result1 = (maybe ? ['foo', 'bar', undefined] : [1] ).filter(id()); +>result1 : Symbol(result1, Decl(arrayFilterBooleanExternalOverload1.ts, 7, 9)) +>(maybe ? ['foo', 'bar', undefined] : [1] ).filter : Symbol(Array.filter, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>maybe : Symbol(maybe, Decl(arrayFilterBooleanExternalOverload1.ts, 3, 13)) +>undefined : Symbol(undefined) +>filter : Symbol(Array.filter, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>id : Symbol(id, Decl(arrayFilterBooleanExternalOverload1.ts, 5, 9)) + + result1; +>result1 : Symbol(result1, Decl(arrayFilterBooleanExternalOverload1.ts, 7, 9)) + + const result2 = ['foo', 'bar', undefined].filter(id()); // want id() = (t: string) => boolean +>result2 : Symbol(result2, Decl(arrayFilterBooleanExternalOverload1.ts, 11, 9)) +>['foo', 'bar', undefined].filter : Symbol(Array.filter, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>undefined : Symbol(undefined) +>filter : Symbol(Array.filter, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>id : Symbol(id, Decl(arrayFilterBooleanExternalOverload1.ts, 5, 9)) + + result2; +>result2 : Symbol(result2, Decl(arrayFilterBooleanExternalOverload1.ts, 11, 9)) +} + diff --git a/tests/baselines/reference/arrayFilterBooleanExternalOverload1.types b/tests/baselines/reference/arrayFilterBooleanExternalOverload1.types new file mode 100644 index 0000000000000..1b6cc5e140983 --- /dev/null +++ b/tests/baselines/reference/arrayFilterBooleanExternalOverload1.types @@ -0,0 +1,54 @@ +//// [tests/cases/compiler/arrayFilterBooleanExternalOverload1.ts] //// + +=== arrayFilterBooleanExternalOverload1.ts === +// #56013 + +// For reference, thise cases work as expected (no errors) when no external BooleanConstrudtor like overload is present +declare const maybe: boolean; +>maybe : boolean +{ + const id = () => (t: T) => !!t; +>id : () => (t: T) => boolean +>() => (t: T) => !!t : () => (t: T) => boolean +>(t: T) => !!t : (t: T) => boolean +>t : T +>!!t : boolean +>!t : boolean +>t : T + + const result1 = (maybe ? ['foo', 'bar', undefined] : [1] ).filter(id()); +>result1 : (string | number | undefined)[] +>(maybe ? ['foo', 'bar', undefined] : [1] ).filter(id()) : (string | number | undefined)[] +>(maybe ? ['foo', 'bar', undefined] : [1] ).filter : { (predicate: (value: string | undefined, index: number, array: (string | undefined)[]) => value is S, thisArg?: any): S[]; (predicate: (value: string | undefined, index: number, array: (string | undefined)[]) => unknown, thisArg?: any): (string | undefined)[]; } | { (predicate: (value: number, index: number, array: number[]) => value is S_1, thisArg?: any): S_1[]; (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any): number[]; } +>(maybe ? ['foo', 'bar', undefined] : [1] ) : (string | undefined)[] | number[] +>maybe ? ['foo', 'bar', undefined] : [1] : (string | undefined)[] | number[] +>maybe : boolean +>['foo', 'bar', undefined] : (string | undefined)[] +>'foo' : "foo" +>'bar' : "bar" +>undefined : undefined +>[1] : number[] +>1 : 1 +>filter : { (predicate: (value: string | undefined, index: number, array: (string | undefined)[]) => value is S, thisArg?: any): S[]; (predicate: (value: string | undefined, index: number, array: (string | undefined)[]) => unknown, thisArg?: any): (string | undefined)[]; } | { (predicate: (value: number, index: number, array: number[]) => value is S_1, thisArg?: any): S_1[]; (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any): number[]; } +>id() : (t: string | number | undefined) => boolean +>id : () => (t: T) => boolean + + result1; +>result1 : (string | number | undefined)[] + + const result2 = ['foo', 'bar', undefined].filter(id()); // want id() = (t: string) => boolean +>result2 : (string | undefined)[] +>['foo', 'bar', undefined].filter(id()) : (string | undefined)[] +>['foo', 'bar', undefined].filter : { (predicate: (value: string | undefined, index: number, array: (string | undefined)[]) => value is S, thisArg?: any): S[]; (predicate: (value: string | undefined, index: number, array: (string | undefined)[]) => unknown, thisArg?: any): (string | undefined)[]; } +>['foo', 'bar', undefined] : (string | undefined)[] +>'foo' : "foo" +>'bar' : "bar" +>undefined : undefined +>filter : { (predicate: (value: string | undefined, index: number, array: (string | undefined)[]) => value is S, thisArg?: any): S[]; (predicate: (value: string | undefined, index: number, array: (string | undefined)[]) => unknown, thisArg?: any): (string | undefined)[]; } +>id() : (t: string | undefined) => boolean +>id : () => (t: T) => boolean + + result2; +>result2 : (string | undefined)[] +} + diff --git a/tests/baselines/reference/arrayFilterBooleanExternalOverload2.errors.txt b/tests/baselines/reference/arrayFilterBooleanExternalOverload2.errors.txt new file mode 100644 index 0000000000000..82136813ca67f --- /dev/null +++ b/tests/baselines/reference/arrayFilterBooleanExternalOverload2.errors.txt @@ -0,0 +1,38 @@ +arrayFilterBooleanExternalOverload2.ts(13,71): error TS2345: Argument of type '(t: unknown) => boolean' is not assignable to parameter of type 'BooleanConstructor & { prototype: unique symbol; }'. + Type '(t: unknown) => boolean' is not assignable to type 'BooleanConstructor'. + Type '(t: unknown) => boolean' provides no match for the signature 'new (value?: any): Boolean'. + + +==== arrayFilterBooleanExternalOverload2.ts (1 errors) ==== + // #56013 + + const symbool = Symbol("MyBooleanSymbol"); + declare const MyBoolean: typeof Boolean & { prototype: typeof symbool }; + interface Array { + filter(predicate: typeof MyBoolean): (T extends (0 | 0n | "" | false | null | undefined) ? never : T)[]; + } + + declare const maybe: boolean; + { + const id = () => (t: T) => !!t; + + const result1 = (maybe ? ['foo', 'bar', undefined] : [1] ).filter(id()); // error before and after fix (so ignore type) + ~~~~ +!!! error TS2345: Argument of type '(t: unknown) => boolean' is not assignable to parameter of type 'BooleanConstructor & { prototype: unique symbol; }'. +!!! error TS2345: Type '(t: unknown) => boolean' is not assignable to type 'BooleanConstructor'. +!!! error TS2345: Type '(t: unknown) => boolean' provides no match for the signature 'new (value?: any): Boolean'. + // Errors before and after fix are different. + // The error in the #56013 fixed case is: + // ~~~~ + // error TS2345: Argument of type '(t: unknown) => boolean' is not assignable to parameter of type 'BooleanConstructor & { prototype: unique symbol; }'. + // error TS2345: Type '(t: unknown) => boolean' is not assignable to type 'BooleanConstructor'. + // error TS2345: Type '(t: unknown) => boolean' provides no match for the signature 'new (value?: any): Boolean'. + + + result1; + + const result2 = ['foo', 'bar', undefined].filter(id()); // want id() = (t: string) => boolean + + result2; + } + \ No newline at end of file diff --git a/tests/baselines/reference/arrayFilterBooleanExternalOverload2.js b/tests/baselines/reference/arrayFilterBooleanExternalOverload2.js new file mode 100644 index 0000000000000..3ef20a3606728 --- /dev/null +++ b/tests/baselines/reference/arrayFilterBooleanExternalOverload2.js @@ -0,0 +1,60 @@ +//// [tests/cases/compiler/arrayFilterBooleanExternalOverload2.ts] //// + +//// [arrayFilterBooleanExternalOverload2.ts] +// #56013 + +const symbool = Symbol("MyBooleanSymbol"); +declare const MyBoolean: typeof Boolean & { prototype: typeof symbool }; +interface Array { + filter(predicate: typeof MyBoolean): (T extends (0 | 0n | "" | false | null | undefined) ? never : T)[]; +} + +declare const maybe: boolean; +{ + const id = () => (t: T) => !!t; + + const result1 = (maybe ? ['foo', 'bar', undefined] : [1] ).filter(id()); // error before and after fix (so ignore type) + // Errors before and after fix are different. + // The error in the #56013 fixed case is: + // ~~~~ + // error TS2345: Argument of type '(t: unknown) => boolean' is not assignable to parameter of type 'BooleanConstructor & { prototype: unique symbol; }'. + // error TS2345: Type '(t: unknown) => boolean' is not assignable to type 'BooleanConstructor'. + // error TS2345: Type '(t: unknown) => boolean' provides no match for the signature 'new (value?: any): Boolean'. + + + result1; + + const result2 = ['foo', 'bar', undefined].filter(id()); // want id() = (t: string) => boolean + + result2; +} + + +//// [arrayFilterBooleanExternalOverload2.js] +"use strict"; +// #56013 +const symbool = Symbol("MyBooleanSymbol"); +{ + const id = () => (t) => !!t; + const result1 = (maybe ? ['foo', 'bar', undefined] : [1]).filter(id()); // error before and after fix (so ignore type) + // Errors before and after fix are different. + // The error in the #56013 fixed case is: + // ~~~~ + // error TS2345: Argument of type '(t: unknown) => boolean' is not assignable to parameter of type 'BooleanConstructor & { prototype: unique symbol; }'. + // error TS2345: Type '(t: unknown) => boolean' is not assignable to type 'BooleanConstructor'. + // error TS2345: Type '(t: unknown) => boolean' provides no match for the signature 'new (value?: any): Boolean'. + result1; + const result2 = ['foo', 'bar', undefined].filter(id()); // want id() = (t: string) => boolean + result2; +} + + +//// [arrayFilterBooleanExternalOverload2.d.ts] +declare const symbool: unique symbol; +declare const MyBoolean: typeof Boolean & { + prototype: typeof symbool; +}; +interface Array { + filter(predicate: typeof MyBoolean): (T extends (0 | 0n | "" | false | null | undefined) ? never : T)[]; +} +declare const maybe: boolean; diff --git a/tests/baselines/reference/arrayFilterBooleanExternalOverload2.symbols b/tests/baselines/reference/arrayFilterBooleanExternalOverload2.symbols new file mode 100644 index 0000000000000..062403d303e31 --- /dev/null +++ b/tests/baselines/reference/arrayFilterBooleanExternalOverload2.symbols @@ -0,0 +1,67 @@ +//// [tests/cases/compiler/arrayFilterBooleanExternalOverload2.ts] //// + +=== arrayFilterBooleanExternalOverload2.ts === +// #56013 + +const symbool = Symbol("MyBooleanSymbol"); +>symbool : Symbol(symbool, Decl(arrayFilterBooleanExternalOverload2.ts, 2, 5)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + +declare const MyBoolean: typeof Boolean & { prototype: typeof symbool }; +>MyBoolean : Symbol(MyBoolean, Decl(arrayFilterBooleanExternalOverload2.ts, 3, 13)) +>Boolean : Symbol(Boolean, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>prototype : Symbol(prototype, Decl(arrayFilterBooleanExternalOverload2.ts, 3, 43)) +>symbool : Symbol(symbool, Decl(arrayFilterBooleanExternalOverload2.ts, 2, 5)) + +interface Array { +>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --) ... and 1 more) +>T : Symbol(T, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(arrayFilterBooleanExternalOverload2.ts, 4, 16)) + + filter(predicate: typeof MyBoolean): (T extends (0 | 0n | "" | false | null | undefined) ? never : T)[]; +>filter : Symbol(Array.filter, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(arrayFilterBooleanExternalOverload2.ts, 4, 20)) +>predicate : Symbol(predicate, Decl(arrayFilterBooleanExternalOverload2.ts, 5, 11)) +>MyBoolean : Symbol(MyBoolean, Decl(arrayFilterBooleanExternalOverload2.ts, 3, 13)) +>T : Symbol(T, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(arrayFilterBooleanExternalOverload2.ts, 4, 16)) +>T : Symbol(T, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(arrayFilterBooleanExternalOverload2.ts, 4, 16)) +} + +declare const maybe: boolean; +>maybe : Symbol(maybe, Decl(arrayFilterBooleanExternalOverload2.ts, 8, 13)) +{ + const id = () => (t: T) => !!t; +>id : Symbol(id, Decl(arrayFilterBooleanExternalOverload2.ts, 10, 9)) +>T : Symbol(T, Decl(arrayFilterBooleanExternalOverload2.ts, 10, 16)) +>t : Symbol(t, Decl(arrayFilterBooleanExternalOverload2.ts, 10, 25)) +>T : Symbol(T, Decl(arrayFilterBooleanExternalOverload2.ts, 10, 16)) +>t : Symbol(t, Decl(arrayFilterBooleanExternalOverload2.ts, 10, 25)) + + const result1 = (maybe ? ['foo', 'bar', undefined] : [1] ).filter(id()); // error before and after fix (so ignore type) +>result1 : Symbol(result1, Decl(arrayFilterBooleanExternalOverload2.ts, 12, 9)) +>(maybe ? ['foo', 'bar', undefined] : [1] ).filter : Symbol(Array.filter, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(arrayFilterBooleanExternalOverload2.ts, 4, 20), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --) ... and 1 more) +>maybe : Symbol(maybe, Decl(arrayFilterBooleanExternalOverload2.ts, 8, 13)) +>undefined : Symbol(undefined) +>filter : Symbol(Array.filter, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(arrayFilterBooleanExternalOverload2.ts, 4, 20), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --) ... and 1 more) +>id : Symbol(id, Decl(arrayFilterBooleanExternalOverload2.ts, 10, 9)) + + // Errors before and after fix are different. + // The error in the #56013 fixed case is: + // ~~~~ + // error TS2345: Argument of type '(t: unknown) => boolean' is not assignable to parameter of type 'BooleanConstructor & { prototype: unique symbol; }'. + // error TS2345: Type '(t: unknown) => boolean' is not assignable to type 'BooleanConstructor'. + // error TS2345: Type '(t: unknown) => boolean' provides no match for the signature 'new (value?: any): Boolean'. + + + result1; +>result1 : Symbol(result1, Decl(arrayFilterBooleanExternalOverload2.ts, 12, 9)) + + const result2 = ['foo', 'bar', undefined].filter(id()); // want id() = (t: string) => boolean +>result2 : Symbol(result2, Decl(arrayFilterBooleanExternalOverload2.ts, 23, 9)) +>['foo', 'bar', undefined].filter : Symbol(Array.filter, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(arrayFilterBooleanExternalOverload2.ts, 4, 20)) +>undefined : Symbol(undefined) +>filter : Symbol(Array.filter, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(arrayFilterBooleanExternalOverload2.ts, 4, 20)) +>id : Symbol(id, Decl(arrayFilterBooleanExternalOverload2.ts, 10, 9)) + + result2; +>result2 : Symbol(result2, Decl(arrayFilterBooleanExternalOverload2.ts, 23, 9)) +} + diff --git a/tests/baselines/reference/arrayFilterBooleanExternalOverload2.types b/tests/baselines/reference/arrayFilterBooleanExternalOverload2.types new file mode 100644 index 0000000000000..895c1ed2b0b8f --- /dev/null +++ b/tests/baselines/reference/arrayFilterBooleanExternalOverload2.types @@ -0,0 +1,81 @@ +//// [tests/cases/compiler/arrayFilterBooleanExternalOverload2.ts] //// + +=== arrayFilterBooleanExternalOverload2.ts === +// #56013 + +const symbool = Symbol("MyBooleanSymbol"); +>symbool : unique symbol +>Symbol("MyBooleanSymbol") : unique symbol +>Symbol : SymbolConstructor +>"MyBooleanSymbol" : "MyBooleanSymbol" + +declare const MyBoolean: typeof Boolean & { prototype: typeof symbool }; +>MyBoolean : BooleanConstructor & { prototype: typeof symbool; } +>Boolean : BooleanConstructor +>prototype : unique symbol +>symbool : unique symbol + +interface Array { + filter(predicate: typeof MyBoolean): (T extends (0 | 0n | "" | false | null | undefined) ? never : T)[]; +>filter : { (predicate: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S[]; (predicate: (value: T, index: number, array: T[]) => unknown, thisArg?: any): T[]; (predicate: typeof MyBoolean): (T extends (0 | 0n | "" | false | null | undefined) ? never : T)[]; } +>predicate : BooleanConstructor & { prototype: unique symbol; } +>MyBoolean : BooleanConstructor & { prototype: unique symbol; } +>false : false +} + +declare const maybe: boolean; +>maybe : boolean +{ + const id = () => (t: T) => !!t; +>id : () => (t: T) => boolean +>() => (t: T) => !!t : () => (t: T) => boolean +>(t: T) => !!t : (t: T) => boolean +>t : T +>!!t : boolean +>!t : boolean +>t : T + + const result1 = (maybe ? ['foo', 'bar', undefined] : [1] ).filter(id()); // error before and after fix (so ignore type) +>result1 : number[] | string[] +>(maybe ? ['foo', 'bar', undefined] : [1] ).filter(id()) : number[] | string[] +>(maybe ? ['foo', 'bar', undefined] : [1] ).filter : { (predicate: (value: string | undefined, index: number, array: (string | undefined)[]) => value is S, thisArg?: any): S[]; (predicate: (value: string | undefined, index: number, array: (string | undefined)[]) => unknown, thisArg?: any): (string | undefined)[]; (predicate: BooleanConstructor & { prototype: unique symbol; }): string[]; } | { (predicate: (value: number, index: number, array: number[]) => value is S_1, thisArg?: any): S_1[]; (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any): number[]; (predicate: BooleanConstructor & { prototype: unique symbol; }): number[]; } +>(maybe ? ['foo', 'bar', undefined] : [1] ) : (string | undefined)[] | number[] +>maybe ? ['foo', 'bar', undefined] : [1] : (string | undefined)[] | number[] +>maybe : boolean +>['foo', 'bar', undefined] : (string | undefined)[] +>'foo' : "foo" +>'bar' : "bar" +>undefined : undefined +>[1] : number[] +>1 : 1 +>filter : { (predicate: (value: string | undefined, index: number, array: (string | undefined)[]) => value is S, thisArg?: any): S[]; (predicate: (value: string | undefined, index: number, array: (string | undefined)[]) => unknown, thisArg?: any): (string | undefined)[]; (predicate: BooleanConstructor & { prototype: unique symbol; }): string[]; } | { (predicate: (value: number, index: number, array: number[]) => value is S_1, thisArg?: any): S_1[]; (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any): number[]; (predicate: BooleanConstructor & { prototype: unique symbol; }): number[]; } +>id() : (t: unknown) => boolean +>id : () => (t: T) => boolean + + // Errors before and after fix are different. + // The error in the #56013 fixed case is: + // ~~~~ + // error TS2345: Argument of type '(t: unknown) => boolean' is not assignable to parameter of type 'BooleanConstructor & { prototype: unique symbol; }'. + // error TS2345: Type '(t: unknown) => boolean' is not assignable to type 'BooleanConstructor'. + // error TS2345: Type '(t: unknown) => boolean' provides no match for the signature 'new (value?: any): Boolean'. + + + result1; +>result1 : number[] | string[] + + const result2 = ['foo', 'bar', undefined].filter(id()); // want id() = (t: string) => boolean +>result2 : (string | undefined)[] +>['foo', 'bar', undefined].filter(id()) : (string | undefined)[] +>['foo', 'bar', undefined].filter : { (predicate: (value: string | undefined, index: number, array: (string | undefined)[]) => value is S, thisArg?: any): S[]; (predicate: (value: string | undefined, index: number, array: (string | undefined)[]) => unknown, thisArg?: any): (string | undefined)[]; (predicate: BooleanConstructor & { prototype: unique symbol; }): string[]; } +>['foo', 'bar', undefined] : (string | undefined)[] +>'foo' : "foo" +>'bar' : "bar" +>undefined : undefined +>filter : { (predicate: (value: string | undefined, index: number, array: (string | undefined)[]) => value is S, thisArg?: any): S[]; (predicate: (value: string | undefined, index: number, array: (string | undefined)[]) => unknown, thisArg?: any): (string | undefined)[]; (predicate: BooleanConstructor & { prototype: unique symbol; }): string[]; } +>id() : (t: unknown) => boolean +>id : () => (t: T) => boolean + + result2; +>result2 : (string | undefined)[] +} + diff --git a/tests/baselines/reference/arrayFilterBooleanExternalOverload3.js b/tests/baselines/reference/arrayFilterBooleanExternalOverload3.js new file mode 100644 index 0000000000000..c7b637da5b723 --- /dev/null +++ b/tests/baselines/reference/arrayFilterBooleanExternalOverload3.js @@ -0,0 +1,47 @@ +//// [tests/cases/compiler/arrayFilterBooleanExternalOverload3.ts] //// + +//// [arrayFilterBooleanExternalOverload3.ts] +// #56013 + +const symbool = Symbol("MyBooleanSymbol"); +declare const MyBoolean: typeof Boolean & { prototype: typeof symbool }; +interface Array { + filter(predicate: typeof MyBoolean): (T extends (0 | 0n | "" | false | null | undefined) ? never : T)[]; +} + +declare const maybe: boolean; +{ + const id = () => (t: T) => !!t; + + const result1 = (maybe ? ['foo', 'bar', undefined] : [1] ).filter(MyBoolean); + + result1; + + const result2 = ['foo', 'bar', undefined].filter(MyBoolean); // want id() = (t: string) => boolean + + result2; +} + + +//// [arrayFilterBooleanExternalOverload3.js] +"use strict"; +// #56013 +const symbool = Symbol("MyBooleanSymbol"); +{ + const id = () => (t) => !!t; + const result1 = (maybe ? ['foo', 'bar', undefined] : [1]).filter(MyBoolean); + result1; + const result2 = ['foo', 'bar', undefined].filter(MyBoolean); // want id() = (t: string) => boolean + result2; +} + + +//// [arrayFilterBooleanExternalOverload3.d.ts] +declare const symbool: unique symbol; +declare const MyBoolean: typeof Boolean & { + prototype: typeof symbool; +}; +interface Array { + filter(predicate: typeof MyBoolean): (T extends (0 | 0n | "" | false | null | undefined) ? never : T)[]; +} +declare const maybe: boolean; diff --git a/tests/baselines/reference/arrayFilterBooleanExternalOverload3.symbols b/tests/baselines/reference/arrayFilterBooleanExternalOverload3.symbols new file mode 100644 index 0000000000000..01dd0160f281d --- /dev/null +++ b/tests/baselines/reference/arrayFilterBooleanExternalOverload3.symbols @@ -0,0 +1,59 @@ +//// [tests/cases/compiler/arrayFilterBooleanExternalOverload3.ts] //// + +=== arrayFilterBooleanExternalOverload3.ts === +// #56013 + +const symbool = Symbol("MyBooleanSymbol"); +>symbool : Symbol(symbool, Decl(arrayFilterBooleanExternalOverload3.ts, 2, 5)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + +declare const MyBoolean: typeof Boolean & { prototype: typeof symbool }; +>MyBoolean : Symbol(MyBoolean, Decl(arrayFilterBooleanExternalOverload3.ts, 3, 13)) +>Boolean : Symbol(Boolean, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>prototype : Symbol(prototype, Decl(arrayFilterBooleanExternalOverload3.ts, 3, 43)) +>symbool : Symbol(symbool, Decl(arrayFilterBooleanExternalOverload3.ts, 2, 5)) + +interface Array { +>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --) ... and 1 more) +>T : Symbol(T, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(arrayFilterBooleanExternalOverload3.ts, 4, 16)) + + filter(predicate: typeof MyBoolean): (T extends (0 | 0n | "" | false | null | undefined) ? never : T)[]; +>filter : Symbol(Array.filter, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(arrayFilterBooleanExternalOverload3.ts, 4, 20)) +>predicate : Symbol(predicate, Decl(arrayFilterBooleanExternalOverload3.ts, 5, 11)) +>MyBoolean : Symbol(MyBoolean, Decl(arrayFilterBooleanExternalOverload3.ts, 3, 13)) +>T : Symbol(T, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(arrayFilterBooleanExternalOverload3.ts, 4, 16)) +>T : Symbol(T, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(arrayFilterBooleanExternalOverload3.ts, 4, 16)) +} + +declare const maybe: boolean; +>maybe : Symbol(maybe, Decl(arrayFilterBooleanExternalOverload3.ts, 8, 13)) +{ + const id = () => (t: T) => !!t; +>id : Symbol(id, Decl(arrayFilterBooleanExternalOverload3.ts, 10, 9)) +>T : Symbol(T, Decl(arrayFilterBooleanExternalOverload3.ts, 10, 16)) +>t : Symbol(t, Decl(arrayFilterBooleanExternalOverload3.ts, 10, 26)) +>T : Symbol(T, Decl(arrayFilterBooleanExternalOverload3.ts, 10, 16)) +>t : Symbol(t, Decl(arrayFilterBooleanExternalOverload3.ts, 10, 26)) + + const result1 = (maybe ? ['foo', 'bar', undefined] : [1] ).filter(MyBoolean); +>result1 : Symbol(result1, Decl(arrayFilterBooleanExternalOverload3.ts, 12, 9)) +>(maybe ? ['foo', 'bar', undefined] : [1] ).filter : Symbol(Array.filter, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(arrayFilterBooleanExternalOverload3.ts, 4, 20), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --) ... and 1 more) +>maybe : Symbol(maybe, Decl(arrayFilterBooleanExternalOverload3.ts, 8, 13)) +>undefined : Symbol(undefined) +>filter : Symbol(Array.filter, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(arrayFilterBooleanExternalOverload3.ts, 4, 20), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --) ... and 1 more) +>MyBoolean : Symbol(MyBoolean, Decl(arrayFilterBooleanExternalOverload3.ts, 3, 13)) + + result1; +>result1 : Symbol(result1, Decl(arrayFilterBooleanExternalOverload3.ts, 12, 9)) + + const result2 = ['foo', 'bar', undefined].filter(MyBoolean); // want id() = (t: string) => boolean +>result2 : Symbol(result2, Decl(arrayFilterBooleanExternalOverload3.ts, 16, 9)) +>['foo', 'bar', undefined].filter : Symbol(Array.filter, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(arrayFilterBooleanExternalOverload3.ts, 4, 20)) +>undefined : Symbol(undefined) +>filter : Symbol(Array.filter, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(arrayFilterBooleanExternalOverload3.ts, 4, 20)) +>MyBoolean : Symbol(MyBoolean, Decl(arrayFilterBooleanExternalOverload3.ts, 3, 13)) + + result2; +>result2 : Symbol(result2, Decl(arrayFilterBooleanExternalOverload3.ts, 16, 9)) +} + diff --git a/tests/baselines/reference/arrayFilterBooleanExternalOverload3.types b/tests/baselines/reference/arrayFilterBooleanExternalOverload3.types new file mode 100644 index 0000000000000..2d184bd0e3de9 --- /dev/null +++ b/tests/baselines/reference/arrayFilterBooleanExternalOverload3.types @@ -0,0 +1,71 @@ +//// [tests/cases/compiler/arrayFilterBooleanExternalOverload3.ts] //// + +=== arrayFilterBooleanExternalOverload3.ts === +// #56013 + +const symbool = Symbol("MyBooleanSymbol"); +>symbool : unique symbol +>Symbol("MyBooleanSymbol") : unique symbol +>Symbol : SymbolConstructor +>"MyBooleanSymbol" : "MyBooleanSymbol" + +declare const MyBoolean: typeof Boolean & { prototype: typeof symbool }; +>MyBoolean : BooleanConstructor & { prototype: typeof symbool; } +>Boolean : BooleanConstructor +>prototype : unique symbol +>symbool : unique symbol + +interface Array { + filter(predicate: typeof MyBoolean): (T extends (0 | 0n | "" | false | null | undefined) ? never : T)[]; +>filter : { (predicate: (value: T, index: number, array: T[]) => value is S, thisArg?: any): S[]; (predicate: (value: T, index: number, array: T[]) => unknown, thisArg?: any): T[]; (predicate: typeof MyBoolean): (T extends (0 | 0n | "" | false | null | undefined) ? never : T)[]; } +>predicate : BooleanConstructor & { prototype: unique symbol; } +>MyBoolean : BooleanConstructor & { prototype: unique symbol; } +>false : false +} + +declare const maybe: boolean; +>maybe : boolean +{ + const id = () => (t: T) => !!t; +>id : () => (t: T) => boolean +>() => (t: T) => !!t : () => (t: T) => boolean +>(t: T) => !!t : (t: T) => boolean +>t : T +>!!t : boolean +>!t : boolean +>t : T + + const result1 = (maybe ? ['foo', 'bar', undefined] : [1] ).filter(MyBoolean); +>result1 : number[] | string[] +>(maybe ? ['foo', 'bar', undefined] : [1] ).filter(MyBoolean) : number[] | string[] +>(maybe ? ['foo', 'bar', undefined] : [1] ).filter : { (predicate: (value: string | undefined, index: number, array: (string | undefined)[]) => value is S, thisArg?: any): S[]; (predicate: (value: string | undefined, index: number, array: (string | undefined)[]) => unknown, thisArg?: any): (string | undefined)[]; (predicate: BooleanConstructor & { prototype: unique symbol; }): string[]; } | { (predicate: (value: number, index: number, array: number[]) => value is S_1, thisArg?: any): S_1[]; (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any): number[]; (predicate: BooleanConstructor & { prototype: unique symbol; }): number[]; } +>(maybe ? ['foo', 'bar', undefined] : [1] ) : (string | undefined)[] | number[] +>maybe ? ['foo', 'bar', undefined] : [1] : (string | undefined)[] | number[] +>maybe : boolean +>['foo', 'bar', undefined] : (string | undefined)[] +>'foo' : "foo" +>'bar' : "bar" +>undefined : undefined +>[1] : number[] +>1 : 1 +>filter : { (predicate: (value: string | undefined, index: number, array: (string | undefined)[]) => value is S, thisArg?: any): S[]; (predicate: (value: string | undefined, index: number, array: (string | undefined)[]) => unknown, thisArg?: any): (string | undefined)[]; (predicate: BooleanConstructor & { prototype: unique symbol; }): string[]; } | { (predicate: (value: number, index: number, array: number[]) => value is S_1, thisArg?: any): S_1[]; (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any): number[]; (predicate: BooleanConstructor & { prototype: unique symbol; }): number[]; } +>MyBoolean : BooleanConstructor & { prototype: unique symbol; } + + result1; +>result1 : number[] | string[] + + const result2 = ['foo', 'bar', undefined].filter(MyBoolean); // want id() = (t: string) => boolean +>result2 : string[] +>['foo', 'bar', undefined].filter(MyBoolean) : string[] +>['foo', 'bar', undefined].filter : { (predicate: (value: string | undefined, index: number, array: (string | undefined)[]) => value is S, thisArg?: any): S[]; (predicate: (value: string | undefined, index: number, array: (string | undefined)[]) => unknown, thisArg?: any): (string | undefined)[]; (predicate: BooleanConstructor & { prototype: unique symbol; }): string[]; } +>['foo', 'bar', undefined] : (string | undefined)[] +>'foo' : "foo" +>'bar' : "bar" +>undefined : undefined +>filter : { (predicate: (value: string | undefined, index: number, array: (string | undefined)[]) => value is S, thisArg?: any): S[]; (predicate: (value: string | undefined, index: number, array: (string | undefined)[]) => unknown, thisArg?: any): (string | undefined)[]; (predicate: BooleanConstructor & { prototype: unique symbol; }): string[]; } +>MyBoolean : BooleanConstructor & { prototype: unique symbol; } + + result2; +>result2 : string[] +} + diff --git a/tests/baselines/reference/arrayFilterBooleanExternalOverload4.errors.txt b/tests/baselines/reference/arrayFilterBooleanExternalOverload4.errors.txt new file mode 100644 index 0000000000000..20b77f1d54a66 --- /dev/null +++ b/tests/baselines/reference/arrayFilterBooleanExternalOverload4.errors.txt @@ -0,0 +1,59 @@ +arrayFilterBooleanExternalOverload4.ts(15,40): error TS2769: No overload matches this call. + The last overload gave the following error. + Argument of type '(i: 1) => 1' is not assignable to parameter of type '(u: 2) => 2'. + Types of parameters 'i' and 'u' are incompatible. + Type '2' is not assignable to type '1'. +arrayFilterBooleanExternalOverload4.ts(16,35): error TS2769: No overload matches this call. + The last overload gave the following error. + Argument of type '(i: 1) => 1' is not assignable to parameter of type '(t: 2) => 2'. + Types of parameters 'i' and 't' are incompatible. + Type '2' is not assignable to type '1'. +arrayFilterBooleanExternalOverload4.ts(17,35): error TS2769: No overload matches this call. + The last overload gave the following error. + Argument of type '(i: 1) => 1' is not assignable to parameter of type '(t: 2) => 2'. + + +==== arrayFilterBooleanExternalOverload4.ts (3 errors) ==== + // #56013 + + interface F2 { + (p1:(t:1)=>T,p2:(u:1)=>U):11; + (p1:(t:1)=>T,p2:(u:U)=>U):19; + (p1:(t:T)=>T,p2:(u:1)=>U):91; + (p1:(t:T)=>T,p2:(u:U)=>U):99; + } + type ID = () => (i:I) => I; + + declare const id: ID; + + + const t11 = (0 as any as F2<1,1>)(id(),id()); + const t12 = (0 as any as F2<1,2>)(id(),id()); + ~~~~ +!!! error TS2769: No overload matches this call. +!!! error TS2769: The last overload gave the following error. +!!! error TS2769: Argument of type '(i: 1) => 1' is not assignable to parameter of type '(u: 2) => 2'. +!!! error TS2769: Types of parameters 'i' and 'u' are incompatible. +!!! error TS2769: Type '2' is not assignable to type '1'. +!!! related TS2771 arrayFilterBooleanExternalOverload4.ts:7:5: The last overload is declared here. + const t21 = (0 as any as F2<2,1>)(id(),id()); + ~~~~ +!!! error TS2769: No overload matches this call. +!!! error TS2769: The last overload gave the following error. +!!! error TS2769: Argument of type '(i: 1) => 1' is not assignable to parameter of type '(t: 2) => 2'. +!!! error TS2769: Types of parameters 'i' and 't' are incompatible. +!!! error TS2769: Type '2' is not assignable to type '1'. +!!! related TS2771 arrayFilterBooleanExternalOverload4.ts:7:5: The last overload is declared here. + const t22 = (0 as any as F2<2,2>)(id(),id()); + ~~~~ +!!! error TS2769: No overload matches this call. +!!! error TS2769: The last overload gave the following error. +!!! error TS2769: Argument of type '(i: 1) => 1' is not assignable to parameter of type '(t: 2) => 2'. +!!! related TS2771 arrayFilterBooleanExternalOverload4.ts:7:5: The last overload is declared here. + + t11 satisfies 11; + t12 satisfies 19; + t21 satisfies 91; + t22 satisfies 99; + + \ No newline at end of file diff --git a/tests/baselines/reference/arrayFilterBooleanExternalOverload4.js b/tests/baselines/reference/arrayFilterBooleanExternalOverload4.js new file mode 100644 index 0000000000000..4e3332c4f9fdc --- /dev/null +++ b/tests/baselines/reference/arrayFilterBooleanExternalOverload4.js @@ -0,0 +1,54 @@ +//// [tests/cases/compiler/arrayFilterBooleanExternalOverload4.ts] //// + +//// [arrayFilterBooleanExternalOverload4.ts] +// #56013 + +interface F2 { + (p1:(t:1)=>T,p2:(u:1)=>U):11; + (p1:(t:1)=>T,p2:(u:U)=>U):19; + (p1:(t:T)=>T,p2:(u:1)=>U):91; + (p1:(t:T)=>T,p2:(u:U)=>U):99; +} +type ID = () => (i:I) => I; + +declare const id: ID; + + +const t11 = (0 as any as F2<1,1>)(id(),id()); +const t12 = (0 as any as F2<1,2>)(id(),id()); +const t21 = (0 as any as F2<2,1>)(id(),id()); +const t22 = (0 as any as F2<2,2>)(id(),id()); + +t11 satisfies 11; +t12 satisfies 19; +t21 satisfies 91; +t22 satisfies 99; + + + +//// [arrayFilterBooleanExternalOverload4.js] +"use strict"; +// #56013 +const t11 = 0(id(), id()); +const t12 = 0(id(), id()); +const t21 = 0(id(), id()); +const t22 = 0(id(), id()); +t11; +t12; +t21; +t22; + + +//// [arrayFilterBooleanExternalOverload4.d.ts] +interface F2 { + (p1: (t: 1) => T, p2: (u: 1) => U): 11; + (p1: (t: 1) => T, p2: (u: U) => U): 19; + (p1: (t: T) => T, p2: (u: 1) => U): 91; + (p1: (t: T) => T, p2: (u: U) => U): 99; +} +type ID = () => (i: I) => I; +declare const id: ID; +declare const t11: 11; +declare const t12: never; +declare const t21: never; +declare const t22: never; diff --git a/tests/baselines/reference/arrayFilterBooleanExternalOverload4.symbols b/tests/baselines/reference/arrayFilterBooleanExternalOverload4.symbols new file mode 100644 index 0000000000000..27acd4369f3ff --- /dev/null +++ b/tests/baselines/reference/arrayFilterBooleanExternalOverload4.symbols @@ -0,0 +1,95 @@ +//// [tests/cases/compiler/arrayFilterBooleanExternalOverload4.ts] //// + +=== arrayFilterBooleanExternalOverload4.ts === +// #56013 + +interface F2 { +>F2 : Symbol(F2, Decl(arrayFilterBooleanExternalOverload4.ts, 0, 0)) +>T : Symbol(T, Decl(arrayFilterBooleanExternalOverload4.ts, 2, 13)) +>U : Symbol(U, Decl(arrayFilterBooleanExternalOverload4.ts, 2, 30)) + + (p1:(t:1)=>T,p2:(u:1)=>U):11; +>p1 : Symbol(p1, Decl(arrayFilterBooleanExternalOverload4.ts, 3, 5)) +>t : Symbol(t, Decl(arrayFilterBooleanExternalOverload4.ts, 3, 9)) +>T : Symbol(T, Decl(arrayFilterBooleanExternalOverload4.ts, 2, 13)) +>p2 : Symbol(p2, Decl(arrayFilterBooleanExternalOverload4.ts, 3, 17)) +>u : Symbol(u, Decl(arrayFilterBooleanExternalOverload4.ts, 3, 21)) +>U : Symbol(U, Decl(arrayFilterBooleanExternalOverload4.ts, 2, 30)) + + (p1:(t:1)=>T,p2:(u:U)=>U):19; +>p1 : Symbol(p1, Decl(arrayFilterBooleanExternalOverload4.ts, 4, 5)) +>t : Symbol(t, Decl(arrayFilterBooleanExternalOverload4.ts, 4, 9)) +>T : Symbol(T, Decl(arrayFilterBooleanExternalOverload4.ts, 2, 13)) +>p2 : Symbol(p2, Decl(arrayFilterBooleanExternalOverload4.ts, 4, 17)) +>u : Symbol(u, Decl(arrayFilterBooleanExternalOverload4.ts, 4, 21)) +>U : Symbol(U, Decl(arrayFilterBooleanExternalOverload4.ts, 2, 30)) +>U : Symbol(U, Decl(arrayFilterBooleanExternalOverload4.ts, 2, 30)) + + (p1:(t:T)=>T,p2:(u:1)=>U):91; +>p1 : Symbol(p1, Decl(arrayFilterBooleanExternalOverload4.ts, 5, 5)) +>t : Symbol(t, Decl(arrayFilterBooleanExternalOverload4.ts, 5, 9)) +>T : Symbol(T, Decl(arrayFilterBooleanExternalOverload4.ts, 2, 13)) +>T : Symbol(T, Decl(arrayFilterBooleanExternalOverload4.ts, 2, 13)) +>p2 : Symbol(p2, Decl(arrayFilterBooleanExternalOverload4.ts, 5, 17)) +>u : Symbol(u, Decl(arrayFilterBooleanExternalOverload4.ts, 5, 21)) +>U : Symbol(U, Decl(arrayFilterBooleanExternalOverload4.ts, 2, 30)) + + (p1:(t:T)=>T,p2:(u:U)=>U):99; +>p1 : Symbol(p1, Decl(arrayFilterBooleanExternalOverload4.ts, 6, 5)) +>t : Symbol(t, Decl(arrayFilterBooleanExternalOverload4.ts, 6, 9)) +>T : Symbol(T, Decl(arrayFilterBooleanExternalOverload4.ts, 2, 13)) +>T : Symbol(T, Decl(arrayFilterBooleanExternalOverload4.ts, 2, 13)) +>p2 : Symbol(p2, Decl(arrayFilterBooleanExternalOverload4.ts, 6, 17)) +>u : Symbol(u, Decl(arrayFilterBooleanExternalOverload4.ts, 6, 21)) +>U : Symbol(U, Decl(arrayFilterBooleanExternalOverload4.ts, 2, 30)) +>U : Symbol(U, Decl(arrayFilterBooleanExternalOverload4.ts, 2, 30)) +} +type ID = () => (i:I) => I; +>ID : Symbol(ID, Decl(arrayFilterBooleanExternalOverload4.ts, 7, 1)) +>I : Symbol(I, Decl(arrayFilterBooleanExternalOverload4.ts, 8, 11)) +>i : Symbol(i, Decl(arrayFilterBooleanExternalOverload4.ts, 8, 20)) +>I : Symbol(I, Decl(arrayFilterBooleanExternalOverload4.ts, 8, 11)) +>I : Symbol(I, Decl(arrayFilterBooleanExternalOverload4.ts, 8, 11)) + +declare const id: ID; +>id : Symbol(id, Decl(arrayFilterBooleanExternalOverload4.ts, 10, 13)) +>ID : Symbol(ID, Decl(arrayFilterBooleanExternalOverload4.ts, 7, 1)) + + +const t11 = (0 as any as F2<1,1>)(id(),id()); +>t11 : Symbol(t11, Decl(arrayFilterBooleanExternalOverload4.ts, 13, 5)) +>F2 : Symbol(F2, Decl(arrayFilterBooleanExternalOverload4.ts, 0, 0)) +>id : Symbol(id, Decl(arrayFilterBooleanExternalOverload4.ts, 10, 13)) +>id : Symbol(id, Decl(arrayFilterBooleanExternalOverload4.ts, 10, 13)) + +const t12 = (0 as any as F2<1,2>)(id(),id()); +>t12 : Symbol(t12, Decl(arrayFilterBooleanExternalOverload4.ts, 14, 5)) +>F2 : Symbol(F2, Decl(arrayFilterBooleanExternalOverload4.ts, 0, 0)) +>id : Symbol(id, Decl(arrayFilterBooleanExternalOverload4.ts, 10, 13)) +>id : Symbol(id, Decl(arrayFilterBooleanExternalOverload4.ts, 10, 13)) + +const t21 = (0 as any as F2<2,1>)(id(),id()); +>t21 : Symbol(t21, Decl(arrayFilterBooleanExternalOverload4.ts, 15, 5)) +>F2 : Symbol(F2, Decl(arrayFilterBooleanExternalOverload4.ts, 0, 0)) +>id : Symbol(id, Decl(arrayFilterBooleanExternalOverload4.ts, 10, 13)) +>id : Symbol(id, Decl(arrayFilterBooleanExternalOverload4.ts, 10, 13)) + +const t22 = (0 as any as F2<2,2>)(id(),id()); +>t22 : Symbol(t22, Decl(arrayFilterBooleanExternalOverload4.ts, 16, 5)) +>F2 : Symbol(F2, Decl(arrayFilterBooleanExternalOverload4.ts, 0, 0)) +>id : Symbol(id, Decl(arrayFilterBooleanExternalOverload4.ts, 10, 13)) +>id : Symbol(id, Decl(arrayFilterBooleanExternalOverload4.ts, 10, 13)) + +t11 satisfies 11; +>t11 : Symbol(t11, Decl(arrayFilterBooleanExternalOverload4.ts, 13, 5)) + +t12 satisfies 19; +>t12 : Symbol(t12, Decl(arrayFilterBooleanExternalOverload4.ts, 14, 5)) + +t21 satisfies 91; +>t21 : Symbol(t21, Decl(arrayFilterBooleanExternalOverload4.ts, 15, 5)) + +t22 satisfies 99; +>t22 : Symbol(t22, Decl(arrayFilterBooleanExternalOverload4.ts, 16, 5)) + + diff --git a/tests/baselines/reference/arrayFilterBooleanExternalOverload4.types b/tests/baselines/reference/arrayFilterBooleanExternalOverload4.types new file mode 100644 index 0000000000000..4db6727b777c9 --- /dev/null +++ b/tests/baselines/reference/arrayFilterBooleanExternalOverload4.types @@ -0,0 +1,103 @@ +//// [tests/cases/compiler/arrayFilterBooleanExternalOverload4.ts] //// + +=== arrayFilterBooleanExternalOverload4.ts === +// #56013 + +interface F2 { + (p1:(t:1)=>T,p2:(u:1)=>U):11; +>p1 : (t: 1) => T +>t : 1 +>p2 : (u: 1) => U +>u : 1 + + (p1:(t:1)=>T,p2:(u:U)=>U):19; +>p1 : (t: 1) => T +>t : 1 +>p2 : (u: U) => U +>u : U + + (p1:(t:T)=>T,p2:(u:1)=>U):91; +>p1 : (t: T) => T +>t : T +>p2 : (u: 1) => U +>u : 1 + + (p1:(t:T)=>T,p2:(u:U)=>U):99; +>p1 : (t: T) => T +>t : T +>p2 : (u: U) => U +>u : U +} +type ID = () => (i:I) => I; +>ID : () => (i: I) => I +>i : I + +declare const id: ID; +>id : ID + + +const t11 = (0 as any as F2<1,1>)(id(),id()); +>t11 : 11 +>(0 as any as F2<1,1>)(id(),id()) : 11 +>(0 as any as F2<1,1>) : F2<1, 1> +>0 as any as F2<1,1> : F2<1, 1> +>0 as any : any +>0 : 0 +>id() : (i: 1) => 1 +>id : ID +>id() : (i: 1) => 1 +>id : ID + +const t12 = (0 as any as F2<1,2>)(id(),id()); +>t12 : never +>(0 as any as F2<1,2>)(id(),id()) : never +>(0 as any as F2<1,2>) : F2<1, 2> +>0 as any as F2<1,2> : F2<1, 2> +>0 as any : any +>0 : 0 +>id() : (i: 1) => 1 +>id : ID +>id() : (i: 1) => 1 +>id : ID + +const t21 = (0 as any as F2<2,1>)(id(),id()); +>t21 : never +>(0 as any as F2<2,1>)(id(),id()) : never +>(0 as any as F2<2,1>) : F2<2, 1> +>0 as any as F2<2,1> : F2<2, 1> +>0 as any : any +>0 : 0 +>id() : (i: 1) => 1 +>id : ID +>id() : (i: 1) => 1 +>id : ID + +const t22 = (0 as any as F2<2,2>)(id(),id()); +>t22 : never +>(0 as any as F2<2,2>)(id(),id()) : never +>(0 as any as F2<2,2>) : F2<2, 2> +>0 as any as F2<2,2> : F2<2, 2> +>0 as any : any +>0 : 0 +>id() : (i: 1) => 1 +>id : ID +>id() : (i: 2) => 2 +>id : ID + +t11 satisfies 11; +>t11 satisfies 11 : 11 +>t11 : 11 + +t12 satisfies 19; +>t12 satisfies 19 : never +>t12 : never + +t21 satisfies 91; +>t21 satisfies 91 : never +>t21 : never + +t22 satisfies 99; +>t22 satisfies 99 : never +>t22 : never + + diff --git a/tests/cases/compiler/arrayFilterBooleanExternalOverload1.ts b/tests/cases/compiler/arrayFilterBooleanExternalOverload1.ts new file mode 100644 index 0000000000000..d85a94382182c --- /dev/null +++ b/tests/cases/compiler/arrayFilterBooleanExternalOverload1.ts @@ -0,0 +1,19 @@ +// @strict: true +// @target: es6 +// @declaration: true + +// #56013 + +// For reference, thise cases work as expected (no errors) when no external BooleanConstrudtor like overload is present +declare const maybe: boolean; +{ + const id = () => (t: T) => !!t; + + const result1 = (maybe ? ['foo', 'bar', undefined] : [1] ).filter(id()); + + result1; + + const result2 = ['foo', 'bar', undefined].filter(id()); // want id() = (t: string) => boolean + + result2; +} diff --git a/tests/cases/compiler/arrayFilterBooleanExternalOverload2.ts b/tests/cases/compiler/arrayFilterBooleanExternalOverload2.ts new file mode 100644 index 0000000000000..5a14517ae5295 --- /dev/null +++ b/tests/cases/compiler/arrayFilterBooleanExternalOverload2.ts @@ -0,0 +1,31 @@ +// @strict: true +// @target: es6 +// @declaration: true + +// #56013 + +const symbool = Symbol("MyBooleanSymbol"); +declare const MyBoolean: typeof Boolean & { prototype: typeof symbool }; +interface Array { + filter(predicate: typeof MyBoolean): (T extends (0 | 0n | "" | false | null | undefined) ? never : T)[]; +} + +declare const maybe: boolean; +{ + const id = () => (t: T) => !!t; + + const result1 = (maybe ? ['foo', 'bar', undefined] : [1] ).filter(id()); // error before and after fix (so ignore type) + // Errors before and after fix are different. + // The error in the #56013 fixed case is: + // ~~~~ + // error TS2345: Argument of type '(t: unknown) => boolean' is not assignable to parameter of type 'BooleanConstructor & { prototype: unique symbol; }'. + // error TS2345: Type '(t: unknown) => boolean' is not assignable to type 'BooleanConstructor'. + // error TS2345: Type '(t: unknown) => boolean' provides no match for the signature 'new (value?: any): Boolean'. + + + result1; + + const result2 = ['foo', 'bar', undefined].filter(id()); // want id() = (t: string) => boolean + + result2; +} diff --git a/tests/cases/compiler/arrayFilterBooleanExternalOverload3.ts b/tests/cases/compiler/arrayFilterBooleanExternalOverload3.ts new file mode 100644 index 0000000000000..687fbeeac6a58 --- /dev/null +++ b/tests/cases/compiler/arrayFilterBooleanExternalOverload3.ts @@ -0,0 +1,24 @@ +// @strict: true +// @target: es6 +// @declaration: true + +// #56013 + +const symbool = Symbol("MyBooleanSymbol"); +declare const MyBoolean: typeof Boolean & { prototype: typeof symbool }; +interface Array { + filter(predicate: typeof MyBoolean): (T extends (0 | 0n | "" | false | null | undefined) ? never : T)[]; +} + +declare const maybe: boolean; +{ + const id = () => (t: T) => !!t; + + const result1 = (maybe ? ['foo', 'bar', undefined] : [1] ).filter(MyBoolean); + + result1; + + const result2 = ['foo', 'bar', undefined].filter(MyBoolean); // want id() = (t: string) => boolean + + result2; +} diff --git a/tests/cases/compiler/arrayFilterBooleanExternalOverload4.ts b/tests/cases/compiler/arrayFilterBooleanExternalOverload4.ts new file mode 100644 index 0000000000000..6efb146329d76 --- /dev/null +++ b/tests/cases/compiler/arrayFilterBooleanExternalOverload4.ts @@ -0,0 +1,27 @@ +// @strict: true +// @target: es6 +// @declaration: true + +// #56013 + +interface F2 { + (p1:(t:1)=>T,p2:(u:1)=>U):11; + (p1:(t:1)=>T,p2:(u:U)=>U):19; + (p1:(t:T)=>T,p2:(u:1)=>U):91; + (p1:(t:T)=>T,p2:(u:U)=>U):99; +} +type ID = () => (i:I) => I; + +declare const id: ID; + + +const t11 = (0 as any as F2<1,1>)(id(),id()); +const t12 = (0 as any as F2<1,2>)(id(),id()); +const t21 = (0 as any as F2<2,1>)(id(),id()); +const t22 = (0 as any as F2<2,2>)(id(),id()); + +t11 satisfies 11; +t12 satisfies 19; +t21 satisfies 91; +t22 satisfies 99; + From 2317daad176e8f99f2d41394a632434a0738330e Mon Sep 17 00:00:00 2001 From: craigphicks <13205732+craigphicks@users.noreply.github.com> Date: Tue, 14 Nov 2023 05:45:02 +0000 Subject: [PATCH 2/6] fixed checker and test results --- src/compiler/checker.ts | 153 ++++++++++-------- .../arrayFilterBooleanExternalOverload2.types | 2 +- ...yFilterBooleanExternalOverload4.errors.txt | 59 ------- .../arrayFilterBooleanExternalOverload4.js | 6 +- .../arrayFilterBooleanExternalOverload4.types | 30 ++-- 5 files changed, 109 insertions(+), 141 deletions(-) delete mode 100644 tests/baselines/reference/arrayFilterBooleanExternalOverload4.errors.txt diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 4a294a2474f26..eee594fcd0ccc 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1487,6 +1487,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { var lastGetCombinedModifierFlagsNode: Declaration | undefined; var lastGetCombinedModifierFlagsResult = ModifierFlags.None; + var chooseOverloadRecursionLevel = -1; // #56013 + var chooseOverloadFlushNodesSignaturesReq: (Set | undefined)[] = []; // #56013 + // for public members that accept a Node or one of its subtypes, we must guard against // synthetic nodes created during transformations by calling `getParseTreeNode`. // for most of these, we perform the guard only on `checker` to avoid any possible @@ -34310,69 +34313,50 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } function chooseOverload(candidates: Signature[], relation: Map, isSingleNonGenericCandidate: boolean, signatureHelpTrailingComma = false) { - candidatesForArgumentError = undefined; - candidateForArgumentArityError = undefined; - candidateForTypeArgumentError = undefined; - - if (isSingleNonGenericCandidate) { - const candidate = candidates[0]; - if (some(typeArguments) || !hasCorrectArity(node, args, candidate, signatureHelpTrailingComma)) { - return undefined; - } - if (getSignatureApplicabilityError(node, args, candidate, relation, CheckMode.Normal, /*reportErrors*/ false, /*containingMessageChain*/ undefined)) { - candidatesForArgumentError = [candidate]; - return undefined; + chooseOverloadRecursionLevel++; // #56013 + chooseOverloadFlushNodesSignaturesReq[chooseOverloadRecursionLevel] = undefined; + const result = (() => { + candidatesForArgumentError = undefined; + candidateForArgumentArityError = undefined; + candidateForTypeArgumentError = undefined; + + if (isSingleNonGenericCandidate) { + const candidate = candidates[0]; + if (some(typeArguments) || !hasCorrectArity(node, args, candidate, signatureHelpTrailingComma)) { + return undefined; + } + if (getSignatureApplicabilityError(node, args, candidate, relation, CheckMode.Normal, /*reportErrors*/ false, /*containingMessageChain*/ undefined)) { + candidatesForArgumentError = [candidate]; + return undefined; + } + return candidate; } - return candidate; - } - for (let candidateIndex = 0; candidateIndex < candidates.length; candidateIndex++) { - const candidate = candidates[candidateIndex]; - if (!hasCorrectTypeArgumentArity(candidate, typeArguments) || !hasCorrectArity(node, args, candidate, signatureHelpTrailingComma)) { - continue; - } + for (let candidateIndex = 0; candidateIndex < candidates.length; candidateIndex++) { + if (candidateIndex > 0) chooseOverloadFlushNodesSignaturesReq[chooseOverloadRecursionLevel] = new Set(); // #56013 + const candidate = candidates[candidateIndex]; + if (!hasCorrectTypeArgumentArity(candidate, typeArguments) || !hasCorrectArity(node, args, candidate, signatureHelpTrailingComma)) { + continue; + } - let checkCandidate: Signature; - let inferenceContext: InferenceContext | undefined; + let checkCandidate: Signature; + let inferenceContext: InferenceContext | undefined; - if (candidate.typeParameters) { - let typeArgumentTypes: Type[] | undefined; - if (some(typeArguments)) { - typeArgumentTypes = checkTypeArguments(candidate, typeArguments, /*reportErrors*/ false); - if (!typeArgumentTypes) { - candidateForTypeArgumentError = candidate; - continue; + if (candidate.typeParameters) { + let typeArgumentTypes: Type[] | undefined; + if (some(typeArguments)) { + typeArgumentTypes = checkTypeArguments(candidate, typeArguments, /*reportErrors*/ false); + if (!typeArgumentTypes) { + candidateForTypeArgumentError = candidate; + continue; + } } - } - else { - inferenceContext = createInferenceContext(candidate.typeParameters, candidate, /*flags*/ isInJSFile(node) ? InferenceFlags.AnyDefault : InferenceFlags.None); - typeArgumentTypes = inferTypeArguments(node, candidate, args, argCheckMode | CheckMode.SkipGenericFunctions, inferenceContext); - argCheckMode |= inferenceContext.flags & InferenceFlags.SkippedGenericFunction ? CheckMode.SkipGenericFunctions : CheckMode.Normal; - } - checkCandidate = getSignatureInstantiation(candidate, typeArgumentTypes, isInJSFile(candidate.declaration), inferenceContext && inferenceContext.inferredTypeParameters); - // If the original signature has a generic rest type, instantiation may produce a - // signature with different arity and we need to perform another arity check. - if (getNonArrayRestType(candidate) && !hasCorrectArity(node, args, checkCandidate, signatureHelpTrailingComma)) { - candidateForArgumentArityError = checkCandidate; - continue; - } - } - else { - checkCandidate = candidate; - } - if (getSignatureApplicabilityError(node, args, checkCandidate, relation, argCheckMode, /*reportErrors*/ false, /*containingMessageChain*/ undefined)) { - // Give preference to error candidates that have no rest parameters (as they are more specific) - (candidatesForArgumentError || (candidatesForArgumentError = [])).push(checkCandidate); - continue; - } - if (argCheckMode) { - // If one or more context sensitive arguments were excluded, we start including - // them now (and keeping do so for any subsequent candidates) and perform a second - // round of type inference and applicability checking for this particular candidate. - argCheckMode = CheckMode.Normal; - if (inferenceContext) { - const typeArgumentTypes = inferTypeArguments(node, candidate, args, argCheckMode, inferenceContext); - checkCandidate = getSignatureInstantiation(candidate, typeArgumentTypes, isInJSFile(candidate.declaration), inferenceContext.inferredTypeParameters); + else { + inferenceContext = createInferenceContext(candidate.typeParameters, candidate, /*flags*/ isInJSFile(node) ? InferenceFlags.AnyDefault : InferenceFlags.None); + typeArgumentTypes = inferTypeArguments(node, candidate, args, argCheckMode | CheckMode.SkipGenericFunctions, inferenceContext); + argCheckMode |= inferenceContext.flags & InferenceFlags.SkippedGenericFunction ? CheckMode.SkipGenericFunctions : CheckMode.Normal; + } + checkCandidate = getSignatureInstantiation(candidate, typeArgumentTypes, isInJSFile(candidate.declaration), inferenceContext && inferenceContext.inferredTypeParameters); // If the original signature has a generic rest type, instantiation may produce a // signature with different arity and we need to perform another arity check. if (getNonArrayRestType(candidate) && !hasCorrectArity(node, args, checkCandidate, signatureHelpTrailingComma)) { @@ -34380,17 +34364,44 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { continue; } } + else { + checkCandidate = candidate; + } if (getSignatureApplicabilityError(node, args, checkCandidate, relation, argCheckMode, /*reportErrors*/ false, /*containingMessageChain*/ undefined)) { // Give preference to error candidates that have no rest parameters (as they are more specific) (candidatesForArgumentError || (candidatesForArgumentError = [])).push(checkCandidate); continue; } + if (argCheckMode) { + // If one or more context sensitive arguments were excluded, we start including + // them now (and keeping do so for any subsequent candidates) and perform a second + // round of type inference and applicability checking for this particular candidate. + argCheckMode = CheckMode.Normal; + if (inferenceContext) { + const typeArgumentTypes = inferTypeArguments(node, candidate, args, argCheckMode, inferenceContext); + checkCandidate = getSignatureInstantiation(candidate, typeArgumentTypes, isInJSFile(candidate.declaration), inferenceContext.inferredTypeParameters); + // If the original signature has a generic rest type, instantiation may produce a + // signature with different arity and we need to perform another arity check. + if (getNonArrayRestType(candidate) && !hasCorrectArity(node, args, checkCandidate, signatureHelpTrailingComma)) { + candidateForArgumentArityError = checkCandidate; + continue; + } + } + if (getSignatureApplicabilityError(node, args, checkCandidate, relation, argCheckMode, /*reportErrors*/ false, /*containingMessageChain*/ undefined)) { + // Give preference to error candidates that have no rest parameters (as they are more specific) + (candidatesForArgumentError || (candidatesForArgumentError = [])).push(checkCandidate); + continue; + } + } + candidates[candidateIndex] = checkCandidate; + return checkCandidate; } - candidates[candidateIndex] = checkCandidate; - return checkCandidate; - } - return undefined; + return undefined; + })(); + chooseOverloadFlushNodesSignaturesReq[chooseOverloadRecursionLevel] = undefined; + chooseOverloadRecursionLevel--; + return result; } } @@ -35159,7 +35170,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // since resolving such signature leads to resolving the potential outer signature, its arguments and thus the very same signature // it's possible that this inner resolution sets the resolvedSignature first. // In such a case we ignore the local result and reuse the correct one that was cached. - if (links.resolvedSignature !== resolvingSignature) { + // [cph 56013] This is buggy - links.resolvedSignature could be `undefined`. Unfortunately flow did not warn us. + // if (links.resolvedSignature !== resolvingSignature) { + // result = links.resolvedSignature; + // } + if (links.resolvedSignature /* #56013 */ && links.resolvedSignature !== resolvingSignature) { result = links.resolvedSignature; } // If signature resolution originated in control flow type analysis (for example to compute the @@ -35167,6 +35182,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // types from the control flow analysis. links.resolvedSignature = flowLoopStart === flowLoopCount ? result : cached; } + Debug.assert(result); // [cph] #56013 return result; } @@ -35361,6 +35377,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } function checkDeprecatedSignature(signature: Signature, node: CallLikeExpression) { + Debug.assert(signature); if (signature.flags & SignatureFlags.IsSignatureCandidateForOverloadFailure) return; if (signature.declaration && signature.declaration.flags & NodeFlags.Deprecated) { const suggestionNode = getDeprecatedSuggestionNode(node); @@ -38932,6 +38949,16 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const saveCurrentNode = currentNode; currentNode = node; instantiationCount = 0; + // #56013 + if (node.kind === SyntaxKind.CallExpression && chooseOverloadRecursionLevel >= 0) { + let setOfNode: Set | undefined; + if (chooseOverloadRecursionLevel >= 0 && (setOfNode = chooseOverloadFlushNodesSignaturesReq[chooseOverloadRecursionLevel])) { + if (!setOfNode.has(node)) { + getNodeLinks(node).resolvedSignature = undefined; + setOfNode.add(node); + } + } + } const uninstantiatedType = checkExpressionWorker(node, checkMode, forceTuple); const type = instantiateTypeWithSingleGenericCallSignature(node, uninstantiatedType, checkMode); if (isConstEnumObjectType(type)) { diff --git a/tests/baselines/reference/arrayFilterBooleanExternalOverload2.types b/tests/baselines/reference/arrayFilterBooleanExternalOverload2.types index 895c1ed2b0b8f..45dd0f45a0f49 100644 --- a/tests/baselines/reference/arrayFilterBooleanExternalOverload2.types +++ b/tests/baselines/reference/arrayFilterBooleanExternalOverload2.types @@ -72,7 +72,7 @@ declare const maybe: boolean; >'bar' : "bar" >undefined : undefined >filter : { (predicate: (value: string | undefined, index: number, array: (string | undefined)[]) => value is S, thisArg?: any): S[]; (predicate: (value: string | undefined, index: number, array: (string | undefined)[]) => unknown, thisArg?: any): (string | undefined)[]; (predicate: BooleanConstructor & { prototype: unique symbol; }): string[]; } ->id() : (t: unknown) => boolean +>id() : (t: string | undefined) => boolean >id : () => (t: T) => boolean result2; diff --git a/tests/baselines/reference/arrayFilterBooleanExternalOverload4.errors.txt b/tests/baselines/reference/arrayFilterBooleanExternalOverload4.errors.txt deleted file mode 100644 index 20b77f1d54a66..0000000000000 --- a/tests/baselines/reference/arrayFilterBooleanExternalOverload4.errors.txt +++ /dev/null @@ -1,59 +0,0 @@ -arrayFilterBooleanExternalOverload4.ts(15,40): error TS2769: No overload matches this call. - The last overload gave the following error. - Argument of type '(i: 1) => 1' is not assignable to parameter of type '(u: 2) => 2'. - Types of parameters 'i' and 'u' are incompatible. - Type '2' is not assignable to type '1'. -arrayFilterBooleanExternalOverload4.ts(16,35): error TS2769: No overload matches this call. - The last overload gave the following error. - Argument of type '(i: 1) => 1' is not assignable to parameter of type '(t: 2) => 2'. - Types of parameters 'i' and 't' are incompatible. - Type '2' is not assignable to type '1'. -arrayFilterBooleanExternalOverload4.ts(17,35): error TS2769: No overload matches this call. - The last overload gave the following error. - Argument of type '(i: 1) => 1' is not assignable to parameter of type '(t: 2) => 2'. - - -==== arrayFilterBooleanExternalOverload4.ts (3 errors) ==== - // #56013 - - interface F2 { - (p1:(t:1)=>T,p2:(u:1)=>U):11; - (p1:(t:1)=>T,p2:(u:U)=>U):19; - (p1:(t:T)=>T,p2:(u:1)=>U):91; - (p1:(t:T)=>T,p2:(u:U)=>U):99; - } - type ID = () => (i:I) => I; - - declare const id: ID; - - - const t11 = (0 as any as F2<1,1>)(id(),id()); - const t12 = (0 as any as F2<1,2>)(id(),id()); - ~~~~ -!!! error TS2769: No overload matches this call. -!!! error TS2769: The last overload gave the following error. -!!! error TS2769: Argument of type '(i: 1) => 1' is not assignable to parameter of type '(u: 2) => 2'. -!!! error TS2769: Types of parameters 'i' and 'u' are incompatible. -!!! error TS2769: Type '2' is not assignable to type '1'. -!!! related TS2771 arrayFilterBooleanExternalOverload4.ts:7:5: The last overload is declared here. - const t21 = (0 as any as F2<2,1>)(id(),id()); - ~~~~ -!!! error TS2769: No overload matches this call. -!!! error TS2769: The last overload gave the following error. -!!! error TS2769: Argument of type '(i: 1) => 1' is not assignable to parameter of type '(t: 2) => 2'. -!!! error TS2769: Types of parameters 'i' and 't' are incompatible. -!!! error TS2769: Type '2' is not assignable to type '1'. -!!! related TS2771 arrayFilterBooleanExternalOverload4.ts:7:5: The last overload is declared here. - const t22 = (0 as any as F2<2,2>)(id(),id()); - ~~~~ -!!! error TS2769: No overload matches this call. -!!! error TS2769: The last overload gave the following error. -!!! error TS2769: Argument of type '(i: 1) => 1' is not assignable to parameter of type '(t: 2) => 2'. -!!! related TS2771 arrayFilterBooleanExternalOverload4.ts:7:5: The last overload is declared here. - - t11 satisfies 11; - t12 satisfies 19; - t21 satisfies 91; - t22 satisfies 99; - - \ No newline at end of file diff --git a/tests/baselines/reference/arrayFilterBooleanExternalOverload4.js b/tests/baselines/reference/arrayFilterBooleanExternalOverload4.js index 4e3332c4f9fdc..23b4c372db118 100644 --- a/tests/baselines/reference/arrayFilterBooleanExternalOverload4.js +++ b/tests/baselines/reference/arrayFilterBooleanExternalOverload4.js @@ -49,6 +49,6 @@ interface F2 { type ID = () => (i: I) => I; declare const id: ID; declare const t11: 11; -declare const t12: never; -declare const t21: never; -declare const t22: never; +declare const t12: 19; +declare const t21: 91; +declare const t22: 99; diff --git a/tests/baselines/reference/arrayFilterBooleanExternalOverload4.types b/tests/baselines/reference/arrayFilterBooleanExternalOverload4.types index 4db6727b777c9..aa23a50aaa99f 100644 --- a/tests/baselines/reference/arrayFilterBooleanExternalOverload4.types +++ b/tests/baselines/reference/arrayFilterBooleanExternalOverload4.types @@ -49,37 +49,37 @@ const t11 = (0 as any as F2<1,1>)(id(),id()); >id : ID const t12 = (0 as any as F2<1,2>)(id(),id()); ->t12 : never ->(0 as any as F2<1,2>)(id(),id()) : never +>t12 : 19 +>(0 as any as F2<1,2>)(id(),id()) : 19 >(0 as any as F2<1,2>) : F2<1, 2> >0 as any as F2<1,2> : F2<1, 2> >0 as any : any >0 : 0 >id() : (i: 1) => 1 >id : ID ->id() : (i: 1) => 1 +>id() : (i: 2) => 2 >id : ID const t21 = (0 as any as F2<2,1>)(id(),id()); ->t21 : never ->(0 as any as F2<2,1>)(id(),id()) : never +>t21 : 91 +>(0 as any as F2<2,1>)(id(),id()) : 91 >(0 as any as F2<2,1>) : F2<2, 1> >0 as any as F2<2,1> : F2<2, 1> >0 as any : any >0 : 0 ->id() : (i: 1) => 1 +>id() : (i: 2) => 2 >id : ID >id() : (i: 1) => 1 >id : ID const t22 = (0 as any as F2<2,2>)(id(),id()); ->t22 : never ->(0 as any as F2<2,2>)(id(),id()) : never +>t22 : 99 +>(0 as any as F2<2,2>)(id(),id()) : 99 >(0 as any as F2<2,2>) : F2<2, 2> >0 as any as F2<2,2> : F2<2, 2> >0 as any : any >0 : 0 ->id() : (i: 1) => 1 +>id() : (i: 2) => 2 >id : ID >id() : (i: 2) => 2 >id : ID @@ -89,15 +89,15 @@ t11 satisfies 11; >t11 : 11 t12 satisfies 19; ->t12 satisfies 19 : never ->t12 : never +>t12 satisfies 19 : 19 +>t12 : 19 t21 satisfies 91; ->t21 satisfies 91 : never ->t21 : never +>t21 satisfies 91 : 91 +>t21 : 91 t22 satisfies 99; ->t22 satisfies 99 : never ->t22 : never +>t22 satisfies 99 : 99 +>t22 : 99 From 77eab82cdbaedd130ac1b41de47a3810184b9e0a Mon Sep 17 00:00:00 2001 From: craigphicks <13205732+craigphicks@users.noreply.github.com> Date: Tue, 14 Nov 2023 09:25:12 -0800 Subject: [PATCH 3/6] in checkExpression(...), reset links.resolvedSignature to global resolvingSignature instead of undefined --- src/compiler/checker.ts | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index eee594fcd0ccc..31288f4ec9103 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -35162,6 +35162,14 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } links.resolvedSignature = resolvingSignature; let result = resolveSignature(node, candidatesOutArray, checkMode || CheckMode.Normal); + /** + * #56013 + * The following is an invariant condition beneath the above call to resolveSignature: + * - links.resolvedSignature is either the global constant readonly value `resolvingSignature` + * - or a calculated signature. + */ + Debug.assert(links.resolvedSignature); + // When CheckMode.SkipGenericFunctions is set we use resolvingSignature to indicate that call // resolution should be deferred. if (result !== resolvingSignature) { @@ -35170,11 +35178,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // since resolving such signature leads to resolving the potential outer signature, its arguments and thus the very same signature // it's possible that this inner resolution sets the resolvedSignature first. // In such a case we ignore the local result and reuse the correct one that was cached. - // [cph 56013] This is buggy - links.resolvedSignature could be `undefined`. Unfortunately flow did not warn us. - // if (links.resolvedSignature !== resolvingSignature) { - // result = links.resolvedSignature; - // } - if (links.resolvedSignature /* #56013 */ && links.resolvedSignature !== resolvingSignature) { + if (links.resolvedSignature !== resolvingSignature) { result = links.resolvedSignature; } // If signature resolution originated in control flow type analysis (for example to compute the @@ -35182,7 +35186,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // types from the control flow analysis. links.resolvedSignature = flowLoopStart === flowLoopCount ? result : cached; } - Debug.assert(result); // [cph] #56013 return result; } @@ -38954,7 +38957,14 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { let setOfNode: Set | undefined; if (chooseOverloadRecursionLevel >= 0 && (setOfNode = chooseOverloadFlushNodesSignaturesReq[chooseOverloadRecursionLevel])) { if (!setOfNode.has(node)) { - getNodeLinks(node).resolvedSignature = undefined; + /** + * #56013 + * The following is an invariant condition beneath the above call to resolveSignature: + * - getNodeLinks(node).resolvedSignature is either the global constant readonly value `resolvingSignature` + * - or a calculated signature. + * Therefore resetting must set to `resolvingSignature` - it means "not yet calculated". + */ + getNodeLinks(node).resolvedSignature = resolvingSignature; setOfNode.add(node); } } From 4789f7441147718fdf94c1cd189da303b63dbe0d Mon Sep 17 00:00:00 2001 From: craigphicks <13205732+craigphicks@users.noreply.github.com> Date: Sun, 26 Nov 2023 18:45:36 -0800 Subject: [PATCH 4/6] tests/cases/compiler/_co/_coXXX.ts --- tests/cases/compiler/_co/_co-56425.ts | 19 +++++++++++++ tests/cases/compiler/_co/_co-amo1.ts | 10 +++++++ tests/cases/compiler/_co/_co-amo2.ts | 9 +++++++ tests/cases/compiler/_co/_co-amo3.ts | 9 +++++++ .../compiler/_co/_co-arrayMapOverload.ts | 27 +++++++++++++++++++ tests/cases/compiler/_co/_co-onionOfArrays.ts | 27 +++++++++++++++++++ tests/cases/compiler/_co/_co-proxy.ts | 16 +++++++++++ 7 files changed, 117 insertions(+) create mode 100644 tests/cases/compiler/_co/_co-56425.ts create mode 100644 tests/cases/compiler/_co/_co-amo1.ts create mode 100644 tests/cases/compiler/_co/_co-amo2.ts create mode 100644 tests/cases/compiler/_co/_co-amo3.ts create mode 100644 tests/cases/compiler/_co/_co-arrayMapOverload.ts create mode 100644 tests/cases/compiler/_co/_co-onionOfArrays.ts create mode 100644 tests/cases/compiler/_co/_co-proxy.ts diff --git a/tests/cases/compiler/_co/_co-56425.ts b/tests/cases/compiler/_co/_co-56425.ts new file mode 100644 index 0000000000000..8a0938cac90f9 --- /dev/null +++ b/tests/cases/compiler/_co/_co-56425.ts @@ -0,0 +1,19 @@ +interface Foo { + defoo(): never; +} + +interface Bar { + defoo(): void; +} + +type Baz = Foo | Bar; + +function defooer(baz: Baz) { + baz.defoo() + // type = void + // aka (never | void) + + return baz + // type = Baz + // should narrow to Bar +} \ No newline at end of file diff --git a/tests/cases/compiler/_co/_co-amo1.ts b/tests/cases/compiler/_co/_co-amo1.ts new file mode 100644 index 0000000000000..d931e518f37f4 --- /dev/null +++ b/tests/cases/compiler/_co/_co-amo1.ts @@ -0,0 +1,10 @@ +// @strict: true +// @declaration: true +// @target: es6 + +declare function strmapgen(x:T):T; +declare const arrsn : string[]|number[]; + +arrsn.map(strmapgen); // 5.2.2 error + + diff --git a/tests/cases/compiler/_co/_co-amo2.ts b/tests/cases/compiler/_co/_co-amo2.ts new file mode 100644 index 0000000000000..f2f29f3ced5a0 --- /dev/null +++ b/tests/cases/compiler/_co/_co-amo2.ts @@ -0,0 +1,9 @@ +// @strict: true +// @declaration: true +// @target: es6 + +declare const arrsn : string[]|number[]; +declare function strmapol(x:string):string; +declare function strmapol(x:number):number; + +arrsn.map(strmapol); // 5.2.2 error diff --git a/tests/cases/compiler/_co/_co-amo3.ts b/tests/cases/compiler/_co/_co-amo3.ts new file mode 100644 index 0000000000000..e3d0f580b8063 --- /dev/null +++ b/tests/cases/compiler/_co/_co-amo3.ts @@ -0,0 +1,9 @@ +// @strict: true +// @declaration: true +// @target: es6 + +declare const arrsn : string[]|number[]; +declare function strmapol(x:string):string; +//declare function strmapol(x:number):number; + +arrsn.map(strmapol); // 5.2.2 error diff --git a/tests/cases/compiler/_co/_co-arrayMapOverload.ts b/tests/cases/compiler/_co/_co-arrayMapOverload.ts new file mode 100644 index 0000000000000..e052fb80f1207 --- /dev/null +++ b/tests/cases/compiler/_co/_co-arrayMapOverload.ts @@ -0,0 +1,27 @@ +// @strict: true +// @declaration: true +// @target: es6 + +declare const arrsn : string[]|number[]; +declare function strmapol(x:string):string; +declare function strmapol(x:number):number; +//declare function strmap(x:number|string):number|string; + +declare function strmapgen(x:T):T; + +//type ID = () => (i: I) => I; + +declare const fstrmapgen: ()=>(x:T)=>T; + +const fstrmapol = ()=>strmapol; + + + + +arrsn.map(strmapgen); // 5.2.2. no error + +arrsn.map(fstrmapgen()); // 5.2.2. error + +arrsn.map(strmapol); // 5.2.2 error + +arrsn.map(fstrmapol()); // 5.2.2. error \ No newline at end of file diff --git a/tests/cases/compiler/_co/_co-onionOfArrays.ts b/tests/cases/compiler/_co/_co-onionOfArrays.ts new file mode 100644 index 0000000000000..231cbeaf7129e --- /dev/null +++ b/tests/cases/compiler/_co/_co-onionOfArrays.ts @@ -0,0 +1,27 @@ +// @strict: true +// @declaration: true +// @target: es6 + +declare const arrsn : string[]|number[]; +declare function strmapol(x:string):string; +declare function strmapol(x:number):number; +//declare function strmap(x:number|string):number|string; + +declare function strmapgen(x:T):T; + +// //type ID = () => (i: I) => I; + +declare const fstrmapgen: ()=>(x:T)=>T; + +// const fstrmapol = ()=>strmapol; + + + + +//arrsn.map(strmapgen); // 5.2.2. no error + +// arrsn.map(fstrmapgen()); // 5.2.2. error + +arrsn.map(strmapol); // 5.2.2 error + +// arrsn.map(fstrmapol()); // 5.2.2. error \ No newline at end of file diff --git a/tests/cases/compiler/_co/_co-proxy.ts b/tests/cases/compiler/_co/_co-proxy.ts new file mode 100644 index 0000000000000..f29fb8b0510f6 --- /dev/null +++ b/tests/cases/compiler/_co/_co-proxy.ts @@ -0,0 +1,16 @@ +// @strict: true +// @target: es6 + + +type AnyTup = [...any[]]; +type FN = (...args:Args)=>Ret; + +declare function fproxy(fn:FN, ...args: A):R; +declare function f1(s:string):number; + +declare function fol1(s:string):string; +declare function fol1(n:number):number; + + + +const x1 = fproxy(f1,"test"); From 2c4bc6d89ad665449104e87948b2e3020ae40464 Mon Sep 17 00:00:00 2001 From: craigphicks <13205732+craigphicks@users.noreply.github.com> Date: Tue, 28 Nov 2023 22:37:33 +0000 Subject: [PATCH 5/6] cosmetic changes to checker.ts --- src/compiler/checker.ts | 23 ++++++++-------- tests/cases/compiler/_co/_co-56425.ts | 19 ------------- tests/cases/compiler/_co/_co-amo1.ts | 10 ------- tests/cases/compiler/_co/_co-amo2.ts | 9 ------- tests/cases/compiler/_co/_co-amo3.ts | 9 ------- .../compiler/_co/_co-arrayMapOverload.ts | 27 ------------------- tests/cases/compiler/_co/_co-onionOfArrays.ts | 27 ------------------- tests/cases/compiler/_co/_co-proxy.ts | 16 ----------- 8 files changed, 11 insertions(+), 129 deletions(-) delete mode 100644 tests/cases/compiler/_co/_co-56425.ts delete mode 100644 tests/cases/compiler/_co/_co-amo1.ts delete mode 100644 tests/cases/compiler/_co/_co-amo2.ts delete mode 100644 tests/cases/compiler/_co/_co-amo3.ts delete mode 100644 tests/cases/compiler/_co/_co-arrayMapOverload.ts delete mode 100644 tests/cases/compiler/_co/_co-onionOfArrays.ts delete mode 100644 tests/cases/compiler/_co/_co-proxy.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 31288f4ec9103..ea02ba4e2f2ae 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1487,8 +1487,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { var lastGetCombinedModifierFlagsNode: Declaration | undefined; var lastGetCombinedModifierFlagsResult = ModifierFlags.None; - var chooseOverloadRecursionLevel = -1; // #56013 - var chooseOverloadFlushNodesSignaturesReq: (Set | undefined)[] = []; // #56013 + var chooseOverloadRecursionLevel = -1; + var chooseOverloadFlushNodesSignaturesReq: (Set | undefined)[] = []; // for public members that accept a Node or one of its subtypes, we must guard against // synthetic nodes created during transformations by calling `getParseTreeNode`. @@ -34313,9 +34313,14 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } function chooseOverload(candidates: Signature[], relation: Map, isSingleNonGenericCandidate: boolean, signatureHelpTrailingComma = false) { - chooseOverloadRecursionLevel++; // #56013 + chooseOverloadRecursionLevel++; chooseOverloadFlushNodesSignaturesReq[chooseOverloadRecursionLevel] = undefined; - const result = (() => { + const result = chooseOverloadWorker(); + chooseOverloadFlushNodesSignaturesReq[chooseOverloadRecursionLevel] = undefined; + chooseOverloadRecursionLevel--; + return result; + + function chooseOverloadWorker(){ candidatesForArgumentError = undefined; candidateForArgumentArityError = undefined; candidateForTypeArgumentError = undefined; @@ -34333,7 +34338,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } for (let candidateIndex = 0; candidateIndex < candidates.length; candidateIndex++) { - if (candidateIndex > 0) chooseOverloadFlushNodesSignaturesReq[chooseOverloadRecursionLevel] = new Set(); // #56013 + if (candidateIndex > 0) chooseOverloadFlushNodesSignaturesReq[chooseOverloadRecursionLevel] = new Set(); const candidate = candidates[candidateIndex]; if (!hasCorrectTypeArgumentArity(candidate, typeArguments) || !hasCorrectArity(node, args, candidate, signatureHelpTrailingComma)) { continue; @@ -34398,10 +34403,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } return undefined; - })(); - chooseOverloadFlushNodesSignaturesReq[chooseOverloadRecursionLevel] = undefined; - chooseOverloadRecursionLevel--; - return result; + } } } @@ -35163,7 +35165,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { links.resolvedSignature = resolvingSignature; let result = resolveSignature(node, candidatesOutArray, checkMode || CheckMode.Normal); /** - * #56013 * The following is an invariant condition beneath the above call to resolveSignature: * - links.resolvedSignature is either the global constant readonly value `resolvingSignature` * - or a calculated signature. @@ -38952,13 +38953,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const saveCurrentNode = currentNode; currentNode = node; instantiationCount = 0; - // #56013 if (node.kind === SyntaxKind.CallExpression && chooseOverloadRecursionLevel >= 0) { let setOfNode: Set | undefined; if (chooseOverloadRecursionLevel >= 0 && (setOfNode = chooseOverloadFlushNodesSignaturesReq[chooseOverloadRecursionLevel])) { if (!setOfNode.has(node)) { /** - * #56013 * The following is an invariant condition beneath the above call to resolveSignature: * - getNodeLinks(node).resolvedSignature is either the global constant readonly value `resolvingSignature` * - or a calculated signature. diff --git a/tests/cases/compiler/_co/_co-56425.ts b/tests/cases/compiler/_co/_co-56425.ts deleted file mode 100644 index 8a0938cac90f9..0000000000000 --- a/tests/cases/compiler/_co/_co-56425.ts +++ /dev/null @@ -1,19 +0,0 @@ -interface Foo { - defoo(): never; -} - -interface Bar { - defoo(): void; -} - -type Baz = Foo | Bar; - -function defooer(baz: Baz) { - baz.defoo() - // type = void - // aka (never | void) - - return baz - // type = Baz - // should narrow to Bar -} \ No newline at end of file diff --git a/tests/cases/compiler/_co/_co-amo1.ts b/tests/cases/compiler/_co/_co-amo1.ts deleted file mode 100644 index d931e518f37f4..0000000000000 --- a/tests/cases/compiler/_co/_co-amo1.ts +++ /dev/null @@ -1,10 +0,0 @@ -// @strict: true -// @declaration: true -// @target: es6 - -declare function strmapgen(x:T):T; -declare const arrsn : string[]|number[]; - -arrsn.map(strmapgen); // 5.2.2 error - - diff --git a/tests/cases/compiler/_co/_co-amo2.ts b/tests/cases/compiler/_co/_co-amo2.ts deleted file mode 100644 index f2f29f3ced5a0..0000000000000 --- a/tests/cases/compiler/_co/_co-amo2.ts +++ /dev/null @@ -1,9 +0,0 @@ -// @strict: true -// @declaration: true -// @target: es6 - -declare const arrsn : string[]|number[]; -declare function strmapol(x:string):string; -declare function strmapol(x:number):number; - -arrsn.map(strmapol); // 5.2.2 error diff --git a/tests/cases/compiler/_co/_co-amo3.ts b/tests/cases/compiler/_co/_co-amo3.ts deleted file mode 100644 index e3d0f580b8063..0000000000000 --- a/tests/cases/compiler/_co/_co-amo3.ts +++ /dev/null @@ -1,9 +0,0 @@ -// @strict: true -// @declaration: true -// @target: es6 - -declare const arrsn : string[]|number[]; -declare function strmapol(x:string):string; -//declare function strmapol(x:number):number; - -arrsn.map(strmapol); // 5.2.2 error diff --git a/tests/cases/compiler/_co/_co-arrayMapOverload.ts b/tests/cases/compiler/_co/_co-arrayMapOverload.ts deleted file mode 100644 index e052fb80f1207..0000000000000 --- a/tests/cases/compiler/_co/_co-arrayMapOverload.ts +++ /dev/null @@ -1,27 +0,0 @@ -// @strict: true -// @declaration: true -// @target: es6 - -declare const arrsn : string[]|number[]; -declare function strmapol(x:string):string; -declare function strmapol(x:number):number; -//declare function strmap(x:number|string):number|string; - -declare function strmapgen(x:T):T; - -//type ID = () => (i: I) => I; - -declare const fstrmapgen: ()=>(x:T)=>T; - -const fstrmapol = ()=>strmapol; - - - - -arrsn.map(strmapgen); // 5.2.2. no error - -arrsn.map(fstrmapgen()); // 5.2.2. error - -arrsn.map(strmapol); // 5.2.2 error - -arrsn.map(fstrmapol()); // 5.2.2. error \ No newline at end of file diff --git a/tests/cases/compiler/_co/_co-onionOfArrays.ts b/tests/cases/compiler/_co/_co-onionOfArrays.ts deleted file mode 100644 index 231cbeaf7129e..0000000000000 --- a/tests/cases/compiler/_co/_co-onionOfArrays.ts +++ /dev/null @@ -1,27 +0,0 @@ -// @strict: true -// @declaration: true -// @target: es6 - -declare const arrsn : string[]|number[]; -declare function strmapol(x:string):string; -declare function strmapol(x:number):number; -//declare function strmap(x:number|string):number|string; - -declare function strmapgen(x:T):T; - -// //type ID = () => (i: I) => I; - -declare const fstrmapgen: ()=>(x:T)=>T; - -// const fstrmapol = ()=>strmapol; - - - - -//arrsn.map(strmapgen); // 5.2.2. no error - -// arrsn.map(fstrmapgen()); // 5.2.2. error - -arrsn.map(strmapol); // 5.2.2 error - -// arrsn.map(fstrmapol()); // 5.2.2. error \ No newline at end of file diff --git a/tests/cases/compiler/_co/_co-proxy.ts b/tests/cases/compiler/_co/_co-proxy.ts deleted file mode 100644 index f29fb8b0510f6..0000000000000 --- a/tests/cases/compiler/_co/_co-proxy.ts +++ /dev/null @@ -1,16 +0,0 @@ -// @strict: true -// @target: es6 - - -type AnyTup = [...any[]]; -type FN = (...args:Args)=>Ret; - -declare function fproxy(fn:FN, ...args: A):R; -declare function f1(s:string):number; - -declare function fol1(s:string):string; -declare function fol1(n:number):number; - - - -const x1 = fproxy(f1,"test"); From e36a090521ba4627e78d898700085bdd34b7dbae Mon Sep 17 00:00:00 2001 From: craigphicks <13205732+craigphicks@users.noreply.github.com> Date: Wed, 29 Nov 2023 22:39:36 -0800 Subject: [PATCH 6/6] dprint fmt checker.ts --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ea02ba4e2f2ae..abd6d9f07f809 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -34320,7 +34320,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { chooseOverloadRecursionLevel--; return result; - function chooseOverloadWorker(){ + function chooseOverloadWorker() { candidatesForArgumentError = undefined; candidateForArgumentArityError = undefined; candidateForTypeArgumentError = undefined;