diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 91346429b1774..101947565e916 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -32422,29 +32422,28 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (!(type.flags & TypeFlags.Union)) { return getContextualCallSignature(type, node); } - let signatureList: Signature[] | undefined; - const types = (type as UnionType).types; - for (const current of types) { - const signature = getContextualCallSignature(current, node); - if (signature) { - if (!signatureList) { - // This signature will contribute to contextual union signature - signatureList = [signature]; - } - else if (!compareSignaturesIdentical(signatureList[0], signature, /*partialMatch*/ false, /*ignoreThisTypes*/ true, /*ignoreReturnTypes*/ true, compareTypesIdentical)) { - // Signatures aren't identical, do not use - return undefined; - } - else { - // Use this signature for contextual union signature - signatureList.push(signature); - } + + let signatures = mapDefined((type as UnionType).types, t => getContextualCallSignature(t, node)); + const functionFlags = getFunctionFlags(node); + if (functionFlags & FunctionFlags.Generator) { + signatures = filter(signatures, s => checkGeneratorInstantiationAssignabilityToReturnType(getReturnTypeOfSignature(s), functionFlags, /*errorNode*/ undefined)); + } + else if (functionFlags & FunctionFlags.Async) { + signatures = filter(signatures, s => !!getAwaitedTypeOfPromise(getReturnTypeOfSignature(s))); + } + signatures.sort((s1, s2) => getMinArgumentCount(s1) - getMinArgumentCount(s2)); + if (!signatures.length) { + return; + } + + for (let i = 1; i < signatures.length; i++) { + if (!compareSignaturesIdentical(signatures[0], signatures[i], /*partialMatch*/ true, /*ignoreThisTypes*/ true, /*ignoreReturnTypes*/ true, compareTypesSubtypeOf)) { + // Signatures aren't identical, do not use + return undefined; } } // Result is union of signatures collected (return type is union of return types of this signature set) - if (signatureList) { - return signatureList.length === 1 ? signatureList[0] : createUnionSignature(signatureList[0], signatureList); - } + return signatures.length === 1 ? signatures[0] : createUnionSignature(signatures[0], signatures); } function checkGrammarRegularExpressionLiteral(node: RegularExpressionLiteral) { diff --git a/tests/baselines/reference/contextualSignatureWithExtraParameters.symbols b/tests/baselines/reference/contextualSignatureWithExtraParameters.symbols new file mode 100644 index 0000000000000..0016764e832c5 --- /dev/null +++ b/tests/baselines/reference/contextualSignatureWithExtraParameters.symbols @@ -0,0 +1,229 @@ +//// [tests/cases/compiler/contextualSignatureWithExtraParameters.ts] //// + +=== contextualSignatureWithExtraParameters.ts === +// https://github.com/microsoft/TypeScript/issues/59309 +function f1( +>f1 : Symbol(f1, Decl(contextualSignatureWithExtraParameters.ts, 0, 0)) + + cb: ((item: number) => void) | ((item: number, extra: string) => void), +>cb : Symbol(cb, Decl(contextualSignatureWithExtraParameters.ts, 1, 12)) +>item : Symbol(item, Decl(contextualSignatureWithExtraParameters.ts, 2, 10)) +>item : Symbol(item, Decl(contextualSignatureWithExtraParameters.ts, 2, 37)) +>extra : Symbol(extra, Decl(contextualSignatureWithExtraParameters.ts, 2, 50)) + + ) {} + +f1((item) => {}); +>f1 : Symbol(f1, Decl(contextualSignatureWithExtraParameters.ts, 0, 0)) +>item : Symbol(item, Decl(contextualSignatureWithExtraParameters.ts, 5, 4)) + +function f2( +>f2 : Symbol(f2, Decl(contextualSignatureWithExtraParameters.ts, 5, 17)) +>T : Symbol(T, Decl(contextualSignatureWithExtraParameters.ts, 7, 12)) + + arr: T[], +>arr : Symbol(arr, Decl(contextualSignatureWithExtraParameters.ts, 7, 15)) +>T : Symbol(T, Decl(contextualSignatureWithExtraParameters.ts, 7, 12)) + + cb: ((item: T) => void) | ((item: T, extra: unknown) => void), +>cb : Symbol(cb, Decl(contextualSignatureWithExtraParameters.ts, 8, 13)) +>item : Symbol(item, Decl(contextualSignatureWithExtraParameters.ts, 9, 10)) +>T : Symbol(T, Decl(contextualSignatureWithExtraParameters.ts, 7, 12)) +>item : Symbol(item, Decl(contextualSignatureWithExtraParameters.ts, 9, 32)) +>T : Symbol(T, Decl(contextualSignatureWithExtraParameters.ts, 7, 12)) +>extra : Symbol(extra, Decl(contextualSignatureWithExtraParameters.ts, 9, 40)) + + ) {} + +f2([1, 2, 3], (item) => {}); +>f2 : Symbol(f2, Decl(contextualSignatureWithExtraParameters.ts, 5, 17)) +>item : Symbol(item, Decl(contextualSignatureWithExtraParameters.ts, 12, 15)) + +export interface AsyncResultCallback { +>AsyncResultCallback : Symbol(AsyncResultCallback, Decl(contextualSignatureWithExtraParameters.ts, 12, 28)) +>T : Symbol(T, Decl(contextualSignatureWithExtraParameters.ts, 14, 37)) +>E : Symbol(E, Decl(contextualSignatureWithExtraParameters.ts, 14, 39)) +>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2022.error.d.ts, --, --)) + + (err?: E | null, result?: T): void; +>err : Symbol(err, Decl(contextualSignatureWithExtraParameters.ts, 15, 5)) +>E : Symbol(E, Decl(contextualSignatureWithExtraParameters.ts, 14, 39)) +>result : Symbol(result, Decl(contextualSignatureWithExtraParameters.ts, 15, 20)) +>T : Symbol(T, Decl(contextualSignatureWithExtraParameters.ts, 14, 37)) +} + +export interface AsyncResultIterator { +>AsyncResultIterator : Symbol(AsyncResultIterator, Decl(contextualSignatureWithExtraParameters.ts, 16, 1)) +>T : Symbol(T, Decl(contextualSignatureWithExtraParameters.ts, 18, 37)) +>R : Symbol(R, Decl(contextualSignatureWithExtraParameters.ts, 18, 39)) +>E : Symbol(E, Decl(contextualSignatureWithExtraParameters.ts, 18, 42)) +>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2022.error.d.ts, --, --)) + + (item: T, callback: AsyncResultCallback): void; +>item : Symbol(item, Decl(contextualSignatureWithExtraParameters.ts, 19, 5)) +>T : Symbol(T, Decl(contextualSignatureWithExtraParameters.ts, 18, 37)) +>callback : Symbol(callback, Decl(contextualSignatureWithExtraParameters.ts, 19, 13)) +>AsyncResultCallback : Symbol(AsyncResultCallback, Decl(contextualSignatureWithExtraParameters.ts, 12, 28)) +>R : Symbol(R, Decl(contextualSignatureWithExtraParameters.ts, 18, 39)) +>E : Symbol(E, Decl(contextualSignatureWithExtraParameters.ts, 18, 42)) +} +export interface AsyncResultIteratorPromise { +>AsyncResultIteratorPromise : Symbol(AsyncResultIteratorPromise, Decl(contextualSignatureWithExtraParameters.ts, 20, 1)) +>T : Symbol(T, Decl(contextualSignatureWithExtraParameters.ts, 21, 44)) +>R : Symbol(R, Decl(contextualSignatureWithExtraParameters.ts, 21, 46)) + + (item: T): Promise; +>item : Symbol(item, Decl(contextualSignatureWithExtraParameters.ts, 22, 5)) +>T : Symbol(T, Decl(contextualSignatureWithExtraParameters.ts, 21, 44)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --)) +>R : Symbol(R, Decl(contextualSignatureWithExtraParameters.ts, 21, 46)) +} + +declare function mapLimit( +>mapLimit : Symbol(mapLimit, Decl(contextualSignatureWithExtraParameters.ts, 23, 1)) +>T : Symbol(T, Decl(contextualSignatureWithExtraParameters.ts, 25, 26)) +>R : Symbol(R, Decl(contextualSignatureWithExtraParameters.ts, 25, 28)) +>E : Symbol(E, Decl(contextualSignatureWithExtraParameters.ts, 25, 31)) +>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2022.error.d.ts, --, --)) + + arr: T[], +>arr : Symbol(arr, Decl(contextualSignatureWithExtraParameters.ts, 25, 43)) +>T : Symbol(T, Decl(contextualSignatureWithExtraParameters.ts, 25, 26)) + + limit: number, +>limit : Symbol(limit, Decl(contextualSignatureWithExtraParameters.ts, 26, 13)) + + iterator: AsyncResultIteratorPromise | AsyncResultIterator, +>iterator : Symbol(iterator, Decl(contextualSignatureWithExtraParameters.ts, 27, 18)) +>AsyncResultIteratorPromise : Symbol(AsyncResultIteratorPromise, Decl(contextualSignatureWithExtraParameters.ts, 20, 1)) +>T : Symbol(T, Decl(contextualSignatureWithExtraParameters.ts, 25, 26)) +>R : Symbol(R, Decl(contextualSignatureWithExtraParameters.ts, 25, 28)) +>AsyncResultIterator : Symbol(AsyncResultIterator, Decl(contextualSignatureWithExtraParameters.ts, 16, 1)) +>T : Symbol(T, Decl(contextualSignatureWithExtraParameters.ts, 25, 26)) +>R : Symbol(R, Decl(contextualSignatureWithExtraParameters.ts, 25, 28)) +>E : Symbol(E, Decl(contextualSignatureWithExtraParameters.ts, 25, 31)) + +): Promise; +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --)) +>R : Symbol(R, Decl(contextualSignatureWithExtraParameters.ts, 25, 28)) + +mapLimit([1,2,3], 3, async (n) => { +>mapLimit : Symbol(mapLimit, Decl(contextualSignatureWithExtraParameters.ts, 23, 1)) +>n : Symbol(n, Decl(contextualSignatureWithExtraParameters.ts, 31, 28)) + + return n ** 2; +>n : Symbol(n, Decl(contextualSignatureWithExtraParameters.ts, 31, 28)) + +}); + +function f3( +>f3 : Symbol(f3, Decl(contextualSignatureWithExtraParameters.ts, 33, 3)) + + cb: ((a: string, b?: string) => void) | ((a: string, ...rest: string[]) => void) +>cb : Symbol(cb, Decl(contextualSignatureWithExtraParameters.ts, 35, 12)) +>a : Symbol(a, Decl(contextualSignatureWithExtraParameters.ts, 36, 10)) +>b : Symbol(b, Decl(contextualSignatureWithExtraParameters.ts, 36, 20)) +>a : Symbol(a, Decl(contextualSignatureWithExtraParameters.ts, 36, 46)) +>rest : Symbol(rest, Decl(contextualSignatureWithExtraParameters.ts, 36, 56)) + + ) {} + +f3((a) => {}); +>f3 : Symbol(f3, Decl(contextualSignatureWithExtraParameters.ts, 33, 3)) +>a : Symbol(a, Decl(contextualSignatureWithExtraParameters.ts, 39, 4)) + +f3((a, b) => {}); +>f3 : Symbol(f3, Decl(contextualSignatureWithExtraParameters.ts, 33, 3)) +>a : Symbol(a, Decl(contextualSignatureWithExtraParameters.ts, 40, 4)) +>b : Symbol(b, Decl(contextualSignatureWithExtraParameters.ts, 40, 6)) + +function f4( +>f4 : Symbol(f4, Decl(contextualSignatureWithExtraParameters.ts, 40, 17)) + + cb: ((a: string, b: string) => void) | ((a: string, ...rest: string[]) => void) +>cb : Symbol(cb, Decl(contextualSignatureWithExtraParameters.ts, 42, 12)) +>a : Symbol(a, Decl(contextualSignatureWithExtraParameters.ts, 43, 10)) +>b : Symbol(b, Decl(contextualSignatureWithExtraParameters.ts, 43, 20)) +>a : Symbol(a, Decl(contextualSignatureWithExtraParameters.ts, 43, 45)) +>rest : Symbol(rest, Decl(contextualSignatureWithExtraParameters.ts, 43, 55)) + + ) {} + +f4((a) => {}); +>f4 : Symbol(f4, Decl(contextualSignatureWithExtraParameters.ts, 40, 17)) +>a : Symbol(a, Decl(contextualSignatureWithExtraParameters.ts, 46, 4)) + +f4((a, b) => {}); +>f4 : Symbol(f4, Decl(contextualSignatureWithExtraParameters.ts, 40, 17)) +>a : Symbol(a, Decl(contextualSignatureWithExtraParameters.ts, 47, 4)) +>b : Symbol(b, Decl(contextualSignatureWithExtraParameters.ts, 47, 6)) + +function f5( +>f5 : Symbol(f5, Decl(contextualSignatureWithExtraParameters.ts, 47, 17)) + + cb: ((a: string, b: string) => void) | ((...rest: string[]) => void) +>cb : Symbol(cb, Decl(contextualSignatureWithExtraParameters.ts, 49, 12)) +>a : Symbol(a, Decl(contextualSignatureWithExtraParameters.ts, 50, 10)) +>b : Symbol(b, Decl(contextualSignatureWithExtraParameters.ts, 50, 20)) +>rest : Symbol(rest, Decl(contextualSignatureWithExtraParameters.ts, 50, 45)) + + ) {} + +f5((a) => {}); +>f5 : Symbol(f5, Decl(contextualSignatureWithExtraParameters.ts, 47, 17)) +>a : Symbol(a, Decl(contextualSignatureWithExtraParameters.ts, 53, 4)) + +f5((a, b) => {}); +>f5 : Symbol(f5, Decl(contextualSignatureWithExtraParameters.ts, 47, 17)) +>a : Symbol(a, Decl(contextualSignatureWithExtraParameters.ts, 54, 4)) +>b : Symbol(b, Decl(contextualSignatureWithExtraParameters.ts, 54, 6)) + +function f6( +>f6 : Symbol(f6, Decl(contextualSignatureWithExtraParameters.ts, 54, 17)) + + cb: ((a: string) => string) | ((a: "a" | "b") => Promise<"a" | "b">) +>cb : Symbol(cb, Decl(contextualSignatureWithExtraParameters.ts, 56, 12)) +>a : Symbol(a, Decl(contextualSignatureWithExtraParameters.ts, 57, 8)) +>a : Symbol(a, Decl(contextualSignatureWithExtraParameters.ts, 57, 34)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --)) + +) {} + +f6(async (a) => a); +>f6 : Symbol(f6, Decl(contextualSignatureWithExtraParameters.ts, 54, 17)) +>a : Symbol(a, Decl(contextualSignatureWithExtraParameters.ts, 60, 10)) +>a : Symbol(a, Decl(contextualSignatureWithExtraParameters.ts, 60, 10)) + +function f7( +>f7 : Symbol(f7, Decl(contextualSignatureWithExtraParameters.ts, 60, 19)) + + cb: ((a: string) => string) | ((a: number) => Generator) +>cb : Symbol(cb, Decl(contextualSignatureWithExtraParameters.ts, 62, 12)) +>a : Symbol(a, Decl(contextualSignatureWithExtraParameters.ts, 63, 8)) +>a : Symbol(a, Decl(contextualSignatureWithExtraParameters.ts, 63, 34)) +>Generator : Symbol(Generator, Decl(lib.es2015.generator.d.ts, --, --)) + +) {} + +f7(function* generator(a) {yield 0}); +>f7 : Symbol(f7, Decl(contextualSignatureWithExtraParameters.ts, 60, 19)) +>generator : Symbol(generator, Decl(contextualSignatureWithExtraParameters.ts, 66, 3)) +>a : Symbol(a, Decl(contextualSignatureWithExtraParameters.ts, 66, 23)) + +function f8( +>f8 : Symbol(f8, Decl(contextualSignatureWithExtraParameters.ts, 66, 37)) + + cb: ((a: string) => string) | ((a: number) => AsyncGenerator) +>cb : Symbol(cb, Decl(contextualSignatureWithExtraParameters.ts, 68, 12)) +>a : Symbol(a, Decl(contextualSignatureWithExtraParameters.ts, 69, 8)) +>a : Symbol(a, Decl(contextualSignatureWithExtraParameters.ts, 69, 34)) +>AsyncGenerator : Symbol(AsyncGenerator, Decl(lib.es2018.asyncgenerator.d.ts, --, --)) + +) {} + +f8(async function* generator(a) {yield 0}); +>f8 : Symbol(f8, Decl(contextualSignatureWithExtraParameters.ts, 66, 37)) +>generator : Symbol(generator, Decl(contextualSignatureWithExtraParameters.ts, 72, 3)) +>a : Symbol(a, Decl(contextualSignatureWithExtraParameters.ts, 72, 29)) + + diff --git a/tests/baselines/reference/contextualSignatureWithExtraParameters.types b/tests/baselines/reference/contextualSignatureWithExtraParameters.types new file mode 100644 index 0000000000000..7b4eea10094be --- /dev/null +++ b/tests/baselines/reference/contextualSignatureWithExtraParameters.types @@ -0,0 +1,342 @@ +//// [tests/cases/compiler/contextualSignatureWithExtraParameters.ts] //// + +=== contextualSignatureWithExtraParameters.ts === +// https://github.com/microsoft/TypeScript/issues/59309 +function f1( +>f1 : (cb: ((item: number) => void) | ((item: number, extra: string) => void)) => void +> : ^ ^^ ^^^^^^^^^ + + cb: ((item: number) => void) | ((item: number, extra: string) => void), +>cb : ((item: number) => void) | ((item: number, extra: string) => void) +> : ^^ ^^ ^^^^^ ^^^^^^ ^^ ^^ ^^ ^^^^^ ^ +>item : number +> : ^^^^^^ +>item : number +> : ^^^^^^ +>extra : string +> : ^^^^^^ + + ) {} + +f1((item) => {}); +>f1((item) => {}) : void +> : ^^^^ +>f1 : (cb: ((item: number) => void) | ((item: number, extra: string) => void)) => void +> : ^ ^^ ^^^^^^^^^ +>(item) => {} : (item: number) => void +> : ^ ^^^^^^^^^^^^^^^^^ +>item : number +> : ^^^^^^ + +function f2( +>f2 : (arr: T[], cb: ((item: T) => void) | ((item: T, extra: unknown) => void)) => void +> : ^ ^^ ^^ ^^ ^^ ^^^^^^^^^ + + arr: T[], +>arr : T[] +> : ^^^ + + cb: ((item: T) => void) | ((item: T, extra: unknown) => void), +>cb : ((item: T) => void) | ((item: T, extra: unknown) => void) +> : ^^ ^^ ^^^^^ ^^^^^^ ^^ ^^ ^^ ^^^^^ ^ +>item : T +> : ^ +>item : T +> : ^ +>extra : unknown +> : ^^^^^^^ + + ) {} + +f2([1, 2, 3], (item) => {}); +>f2([1, 2, 3], (item) => {}) : void +> : ^^^^ +>f2 : (arr: T[], cb: ((item: T) => void) | ((item: T, extra: unknown) => void)) => void +> : ^ ^^ ^^ ^^ ^^ ^^^^^^^^^ +>[1, 2, 3] : number[] +> : ^^^^^^^^ +>1 : 1 +> : ^ +>2 : 2 +> : ^ +>3 : 3 +> : ^ +>(item) => {} : (item: number) => void +> : ^ ^^^^^^^^^^^^^^^^^ +>item : number +> : ^^^^^^ + +export interface AsyncResultCallback { + (err?: E | null, result?: T): void; +>err : E | null | undefined +> : ^^^^^^^^^^^^^^^^^^^^ +>result : T | undefined +> : ^^^^^^^^^^^^^ +} + +export interface AsyncResultIterator { + (item: T, callback: AsyncResultCallback): void; +>item : T +> : ^ +>callback : AsyncResultCallback +> : ^^^^^^^^^^^^^^^^^^^^^^^^^ +} +export interface AsyncResultIteratorPromise { + (item: T): Promise; +>item : T +> : ^ +} + +declare function mapLimit( +>mapLimit : (arr: T[], limit: number, iterator: AsyncResultIteratorPromise | AsyncResultIterator) => Promise +> : ^ ^^ ^^ ^^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^^^^ + + arr: T[], +>arr : T[] +> : ^^^ + + limit: number, +>limit : number +> : ^^^^^^ + + iterator: AsyncResultIteratorPromise | AsyncResultIterator, +>iterator : AsyncResultIteratorPromise | AsyncResultIterator +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +): Promise; + +mapLimit([1,2,3], 3, async (n) => { +>mapLimit([1,2,3], 3, async (n) => { return n ** 2;}) : Promise +> : ^^^^^^^^^^^^^^^^^ +>mapLimit : (arr: T[], limit: number, iterator: AsyncResultIteratorPromise | AsyncResultIterator) => Promise +> : ^ ^^ ^^ ^^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^^^^ +>[1,2,3] : number[] +> : ^^^^^^^^ +>1 : 1 +> : ^ +>2 : 2 +> : ^ +>3 : 3 +> : ^ +>3 : 3 +> : ^ +>async (n) => { return n ** 2;} : (n: number) => Promise +> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>n : number +> : ^^^^^^ + + return n ** 2; +>n ** 2 : number +> : ^^^^^^ +>n : number +> : ^^^^^^ +>2 : 2 +> : ^ + +}); + +function f3( +>f3 : (cb: ((a: string, b?: string) => void) | ((a: string, ...rest: string[]) => void)) => void +> : ^ ^^ ^^^^^^^^^ + + cb: ((a: string, b?: string) => void) | ((a: string, ...rest: string[]) => void) +>cb : ((a: string, b?: string) => void) | ((a: string, ...rest: string[]) => void) +> : ^^ ^^ ^^ ^^^ ^^^^^ ^^^^^^ ^^ ^^^^^ ^^ ^^^^^ ^ +>a : string +> : ^^^^^^ +>b : string | undefined +> : ^^^^^^^^^^^^^^^^^^ +>a : string +> : ^^^^^^ +>rest : string[] +> : ^^^^^^^^ + + ) {} + +f3((a) => {}); +>f3((a) => {}) : void +> : ^^^^ +>f3 : (cb: ((a: string, b?: string) => void) | ((a: string, ...rest: string[]) => void)) => void +> : ^ ^^ ^^^^^^^^^ +>(a) => {} : (a: string) => void +> : ^ ^^^^^^^^^^^^^^^^^ +>a : string +> : ^^^^^^ + +f3((a, b) => {}); +>f3((a, b) => {}) : void +> : ^^^^ +>f3 : (cb: ((a: string, b?: string) => void) | ((a: string, ...rest: string[]) => void)) => void +> : ^ ^^ ^^^^^^^^^ +>(a, b) => {} : (a: string, b: string | undefined) => void +> : ^ ^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>a : string +> : ^^^^^^ +>b : string | undefined +> : ^^^^^^^^^^^^^^^^^^ + +function f4( +>f4 : (cb: ((a: string, b: string) => void) | ((a: string, ...rest: string[]) => void)) => void +> : ^ ^^ ^^^^^^^^^ + + cb: ((a: string, b: string) => void) | ((a: string, ...rest: string[]) => void) +>cb : ((a: string, b: string) => void) | ((a: string, ...rest: string[]) => void) +> : ^^ ^^ ^^ ^^ ^^^^^ ^^^^^^ ^^ ^^^^^ ^^ ^^^^^ ^ +>a : string +> : ^^^^^^ +>b : string +> : ^^^^^^ +>a : string +> : ^^^^^^ +>rest : string[] +> : ^^^^^^^^ + + ) {} + +f4((a) => {}); +>f4((a) => {}) : void +> : ^^^^ +>f4 : (cb: ((a: string, b: string) => void) | ((a: string, ...rest: string[]) => void)) => void +> : ^ ^^ ^^^^^^^^^ +>(a) => {} : (a: string) => void +> : ^ ^^^^^^^^^^^^^^^^^ +>a : string +> : ^^^^^^ + +f4((a, b) => {}); +>f4((a, b) => {}) : void +> : ^^^^ +>f4 : (cb: ((a: string, b: string) => void) | ((a: string, ...rest: string[]) => void)) => void +> : ^ ^^ ^^^^^^^^^ +>(a, b) => {} : (a: string, b: string) => void +> : ^ ^^^^^^^^^^ ^^^^^^^^^^^^^^^^^ +>a : string +> : ^^^^^^ +>b : string +> : ^^^^^^ + +function f5( +>f5 : (cb: ((a: string, b: string) => void) | ((...rest: string[]) => void)) => void +> : ^ ^^ ^^^^^^^^^ + + cb: ((a: string, b: string) => void) | ((...rest: string[]) => void) +>cb : ((a: string, b: string) => void) | ((...rest: string[]) => void) +> : ^^ ^^ ^^ ^^ ^^^^^ ^^^^^^^^^ ^^ ^^^^^ ^ +>a : string +> : ^^^^^^ +>b : string +> : ^^^^^^ +>rest : string[] +> : ^^^^^^^^ + + ) {} + +f5((a) => {}); +>f5((a) => {}) : void +> : ^^^^ +>f5 : (cb: ((a: string, b: string) => void) | ((...rest: string[]) => void)) => void +> : ^ ^^ ^^^^^^^^^ +>(a) => {} : (a: string) => void +> : ^ ^^^^^^^^^^^^^^^^^ +>a : string +> : ^^^^^^ + +f5((a, b) => {}); +>f5((a, b) => {}) : void +> : ^^^^ +>f5 : (cb: ((a: string, b: string) => void) | ((...rest: string[]) => void)) => void +> : ^ ^^ ^^^^^^^^^ +>(a, b) => {} : (a: string, b: string) => void +> : ^ ^^^^^^^^^^ ^^^^^^^^^^^^^^^^^ +>a : string +> : ^^^^^^ +>b : string +> : ^^^^^^ + +function f6( +>f6 : (cb: ((a: string) => string) | ((a: "a" | "b") => Promise<"a" | "b">)) => void +> : ^ ^^ ^^^^^^^^^ + + cb: ((a: string) => string) | ((a: "a" | "b") => Promise<"a" | "b">) +>cb : ((a: string) => string) | ((a: "a" | "b") => Promise<"a" | "b">) +> : ^^ ^^ ^^^^^ ^^^^^^ ^^ ^^^^^ ^ +>a : string +> : ^^^^^^ +>a : "a" | "b" +> : ^^^^^^^^^ + +) {} + +f6(async (a) => a); +>f6(async (a) => a) : void +> : ^^^^ +>f6 : (cb: ((a: string) => string) | ((a: "a" | "b") => Promise<"a" | "b">)) => void +> : ^ ^^ ^^^^^^^^^ +>async (a) => a : (a: "a" | "b") => Promise<"a" | "b"> +> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>a : "a" | "b" +> : ^^^^^^^^^ +>a : "a" | "b" +> : ^^^^^^^^^ + +function f7( +>f7 : (cb: ((a: string) => string) | ((a: number) => Generator)) => void +> : ^ ^^ ^^^^^^^^^ + + cb: ((a: string) => string) | ((a: number) => Generator) +>cb : ((a: string) => string) | ((a: number) => Generator) +> : ^^ ^^ ^^^^^ ^^^^^^ ^^ ^^^^^ ^ +>a : string +> : ^^^^^^ +>a : number +> : ^^^^^^ + +) {} + +f7(function* generator(a) {yield 0}); +>f7(function* generator(a) {yield 0}) : void +> : ^^^^ +>f7 : (cb: ((a: string) => string) | ((a: number) => Generator)) => void +> : ^ ^^ ^^^^^^^^^ +>function* generator(a) {yield 0} : (a: number) => Generator +> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>generator : (a: number) => Generator +> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>a : number +> : ^^^^^^ +>yield 0 : unknown +> : ^^^^^^^ +>0 : 0 +> : ^ + +function f8( +>f8 : (cb: ((a: string) => string) | ((a: number) => AsyncGenerator)) => void +> : ^ ^^ ^^^^^^^^^ + + cb: ((a: string) => string) | ((a: number) => AsyncGenerator) +>cb : ((a: string) => string) | ((a: number) => AsyncGenerator) +> : ^^ ^^ ^^^^^ ^^^^^^ ^^ ^^^^^ ^ +>a : string +> : ^^^^^^ +>a : number +> : ^^^^^^ + +) {} + +f8(async function* generator(a) {yield 0}); +>f8(async function* generator(a) {yield 0}) : void +> : ^^^^ +>f8 : (cb: ((a: string) => string) | ((a: number) => AsyncGenerator)) => void +> : ^ ^^ ^^^^^^^^^ +>async function* generator(a) {yield 0} : (a: number) => AsyncGenerator +> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>generator : (a: number) => AsyncGenerator +> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>a : number +> : ^^^^^^ +>yield 0 : unknown +> : ^^^^^^^ +>0 : 0 +> : ^ + + diff --git a/tests/cases/compiler/contextualSignatureWithExtraParameters.ts b/tests/cases/compiler/contextualSignatureWithExtraParameters.ts new file mode 100644 index 0000000000000..a5382c0c4dc96 --- /dev/null +++ b/tests/cases/compiler/contextualSignatureWithExtraParameters.ts @@ -0,0 +1,79 @@ +// @strict: true +// @target: esnext +// @lib: esnext +// @noEmit: true + +// https://github.com/microsoft/TypeScript/issues/59309 +function f1( + cb: ((item: number) => void) | ((item: number, extra: string) => void), + ) {} + +f1((item) => {}); + +function f2( + arr: T[], + cb: ((item: T) => void) | ((item: T, extra: unknown) => void), + ) {} + +f2([1, 2, 3], (item) => {}); + +export interface AsyncResultCallback { + (err?: E | null, result?: T): void; +} + +export interface AsyncResultIterator { + (item: T, callback: AsyncResultCallback): void; +} +export interface AsyncResultIteratorPromise { + (item: T): Promise; +} + +declare function mapLimit( + arr: T[], + limit: number, + iterator: AsyncResultIteratorPromise | AsyncResultIterator, +): Promise; + +mapLimit([1,2,3], 3, async (n) => { + return n ** 2; +}); + +function f3( + cb: ((a: string, b?: string) => void) | ((a: string, ...rest: string[]) => void) + ) {} + +f3((a) => {}); +f3((a, b) => {}); + +function f4( + cb: ((a: string, b: string) => void) | ((a: string, ...rest: string[]) => void) + ) {} + +f4((a) => {}); +f4((a, b) => {}); + +function f5( + cb: ((a: string, b: string) => void) | ((...rest: string[]) => void) + ) {} + +f5((a) => {}); +f5((a, b) => {}); + +function f6( + cb: ((a: string) => string) | ((a: "a" | "b") => Promise<"a" | "b">) +) {} + +f6(async (a) => a); + +function f7( + cb: ((a: string) => string) | ((a: number) => Generator) +) {} + +f7(function* generator(a) {yield 0}); + +function f8( + cb: ((a: string) => string) | ((a: number) => AsyncGenerator) +) {} + +f8(async function* generator(a) {yield 0}); +