diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index af0df131e9c..8f3f28964c1 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13202,12 +13202,13 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const paramSymbol = createSymbol( SymbolFlags.FunctionScopedVariable | (isOptional && !isRestParam ? SymbolFlags.Optional : 0), paramName || `arg${i}` as __String, + isRestParam ? CheckFlags.RestParameter : isOptional ? CheckFlags.OptionalParameter : 0, ); paramSymbol.links.type = isRestParam ? createArrayType(unionParamType) : unionParamType; params[i] = paramSymbol; } if (needsExtraRestElement) { - const restParamSymbol = createSymbol(SymbolFlags.FunctionScopedVariable, "args" as __String); + const restParamSymbol = createSymbol(SymbolFlags.FunctionScopedVariable, "args" as __String, CheckFlags.RestParameter); restParamSymbol.links.type = createArrayType(getTypeAtPosition(shorter, longestCount)); if (shorter === right) { restParamSymbol.links.type = instantiateType(restParamSymbol.links.type, mapper); diff --git a/tests/baselines/reference/completionEntryForUnionMethod.baseline b/tests/baselines/reference/completionEntryForUnionMethod.baseline index 8592e21eae6..58065fd8d6a 100644 --- a/tests/baselines/reference/completionEntryForUnionMethod.baseline +++ b/tests/baselines/reference/completionEntryForUnionMethod.baseline @@ -6,25 +6,25 @@ // | (method) Array.concat(...items: ConcatArray[]): (string | number)[] (+1 overload) // | (method) Array.every(predicate: (value: string | number, index: number, array: (string | number)[]) => value is S, thisArg?: any): this is S[] (+1 overload) // | (method) Array.filter(predicate: (value: string | number, index: number, array: (string | number)[]) => value is S, thisArg?: any): S[] (+1 overload) -// | (method) Array.forEach(callbackfn: ((value: string, index: number, array: string[]) => void) & ((value: number, index: number, array: number[]) => void), thisArg: any): void -// | (method) Array.indexOf(searchElement: never, fromIndex: number): number +// | (method) Array.forEach(callbackfn: ((value: string, index: number, array: string[]) => void) & ((value: number, index: number, array: number[]) => void), thisArg?: any): void +// | (method) Array.indexOf(searchElement: never, fromIndex?: number): number // | (method) Array.join(separator?: string): string -// | (method) Array.lastIndexOf(searchElement: never, fromIndex: number): number +// | (method) Array.lastIndexOf(searchElement: never, fromIndex?: number): number // | (property) Array.length: number -// | (method) Array.map(callbackfn: ((value: string, index: number, array: string[]) => unknown) & ((value: number, index: number, array: number[]) => unknown), thisArg: any): unknown[] +// | (method) Array.map(callbackfn: ((value: string, index: number, array: string[]) => unknown) & ((value: number, index: number, array: number[]) => unknown), thisArg?: any): unknown[] // | (method) Array.pop(): string | number -// | (method) Array.push(items: never[]): number +// | (method) Array.push(...items: never[]): number // | (method) Array.reduce(callbackfn: (previousValue: string | number, currentValue: string | number, currentIndex: number, array: (string | number)[]) => string | number): string | number (+2 overloads) // | (method) Array.reduceRight(callbackfn: (previousValue: string | number, currentValue: string | number, currentIndex: number, array: (string | number)[]) => string | number): string | number (+2 overloads) // | (method) Array.reverse(): string[] | number[] // | (method) Array.shift(): string | number // | (method) Array.slice(start?: number, end?: number): string[] | number[] -// | (method) Array.some(predicate: ((value: string, index: number, array: string[]) => unknown) & ((value: number, index: number, array: number[]) => unknown), thisArg: any): boolean -// | (method) Array.sort(compareFn: ((a: string, b: string) => number) & ((a: number, b: number) => number)): string[] | number[] +// | (method) Array.some(predicate: ((value: string, index: number, array: string[]) => unknown) & ((value: number, index: number, array: number[]) => unknown), thisArg?: any): boolean +// | (method) Array.sort(compareFn?: ((a: string, b: string) => number) & ((a: number, b: number) => number)): string[] | number[] // | (method) Array.splice(start: number, deleteCount?: number): string[] | number[] (+2 overloads) // | (method) Array.toLocaleString(): string // | (method) Array.toString(): string -// | (method) Array.unshift(items: never[]): number +// | (method) Array.unshift(...items: never[]): number // | ---------------------------------------------------------------------- [ @@ -1263,6 +1263,10 @@ "text": "thisArg", "kind": "parameterName" }, + { + "text": "?", + "kind": "punctuation" + }, { "text": ":", "kind": "punctuation" @@ -1413,6 +1417,10 @@ "text": "fromIndex", "kind": "parameterName" }, + { + "text": "?", + "kind": "punctuation" + }, { "text": ":", "kind": "punctuation" @@ -1676,6 +1684,10 @@ "text": "fromIndex", "kind": "parameterName" }, + { + "text": "?", + "kind": "punctuation" + }, { "text": ":", "kind": "punctuation" @@ -2120,6 +2132,10 @@ "text": "thisArg", "kind": "parameterName" }, + { + "text": "?", + "kind": "punctuation" + }, { "text": ":", "kind": "punctuation" @@ -2340,6 +2356,10 @@ "text": "(", "kind": "punctuation" }, + { + "text": "...", + "kind": "punctuation" + }, { "text": "items", "kind": "parameterName" @@ -3803,6 +3823,10 @@ "text": "thisArg", "kind": "parameterName" }, + { + "text": "?", + "kind": "punctuation" + }, { "text": ":", "kind": "punctuation" @@ -3929,6 +3953,10 @@ "text": "compareFn", "kind": "parameterName" }, + { + "text": "?", + "kind": "punctuation" + }, { "text": ":", "kind": "punctuation" @@ -4589,6 +4617,10 @@ "text": "(", "kind": "punctuation" }, + { + "text": "...", + "kind": "punctuation" + }, { "text": "items", "kind": "parameterName" diff --git a/tests/cases/fourslash/completionEntryForUnionMethod.ts b/tests/cases/fourslash/completionEntryForUnionMethod.ts index 2804a373fd2..48dce525f32 100644 --- a/tests/cases/fourslash/completionEntryForUnionMethod.ts +++ b/tests/cases/fourslash/completionEntryForUnionMethod.ts @@ -3,7 +3,7 @@ ////var y: Array|Array; ////y.map/**/( -const text = "(method) Array.map(callbackfn: ((value: string, index: number, array: string[]) => unknown) & ((value: number, index: number, array: number[]) => unknown), thisArg: any): unknown[]"; +const text = "(method) Array.map(callbackfn: ((value: string, index: number, array: string[]) => unknown) & ((value: number, index: number, array: number[]) => unknown), thisArg?: any): unknown[]"; const documentation = "Calls a defined callback function on each element of an array, and returns an array that contains the results."; verify.quickInfoAt("", text, documentation); diff --git a/tests/cases/fourslash/quickInfoSignatureOptionalParameterFromUnion1.ts b/tests/cases/fourslash/quickInfoSignatureOptionalParameterFromUnion1.ts new file mode 100644 index 00000000000..dce4bfdf0ad --- /dev/null +++ b/tests/cases/fourslash/quickInfoSignatureOptionalParameterFromUnion1.ts @@ -0,0 +1,18 @@ +/// + +// https://github.com/microsoft/TypeScript/issues/55574 + +//// declare const optionals: +//// | ((a?: { a: true }) => unknown) +//// | ((b?: { b: true }) => unknown); +//// +//// /**/optionals(); + +verify.quickInfoAt( + "", + `const optionals: (arg0?: { + a: true; +} & { + b: true; +}) => unknown`, +); diff --git a/tests/cases/fourslash/quickInfoSignatureRestParameterFromUnion1.ts b/tests/cases/fourslash/quickInfoSignatureRestParameterFromUnion1.ts new file mode 100644 index 00000000000..f407a3a4713 --- /dev/null +++ b/tests/cases/fourslash/quickInfoSignatureRestParameterFromUnion1.ts @@ -0,0 +1,18 @@ +/// + +// based on https://github.com/microsoft/TypeScript/issues/55574 + +//// declare const rest: +//// | ((v: { a: true }, ...rest: string[]) => unknown) +//// | ((v: { b: true }) => unknown); +//// +//// /**/rest({ a: true, b: true }, "foo", "bar"); + +verify.quickInfoAt( + "", + `const rest: (v: { + a: true; +} & { + b: true; +}, ...rest: string[]) => unknown`, +); diff --git a/tests/cases/fourslash/quickInfoSignatureRestParameterFromUnion2.ts b/tests/cases/fourslash/quickInfoSignatureRestParameterFromUnion2.ts new file mode 100644 index 00000000000..d53beebd5d8 --- /dev/null +++ b/tests/cases/fourslash/quickInfoSignatureRestParameterFromUnion2.ts @@ -0,0 +1,18 @@ +/// + +// https://github.com/microsoft/TypeScript/issues/55574 + +//// declare const rest: +//// | ((a?: { a: true }, ...rest: string[]) => unknown) +//// | ((b?: { b: true }) => unknown); +//// +//// /**/rest({ a: true, b: true }, "foo", "bar"); + +verify.quickInfoAt( + "", + `const rest: (arg0?: { + a: true; +} & { + b: true; +}, ...rest: string[]) => unknown`, +); diff --git a/tests/cases/fourslash/quickInfoSignatureRestParameterFromUnion3.ts b/tests/cases/fourslash/quickInfoSignatureRestParameterFromUnion3.ts new file mode 100644 index 00000000000..506ab9942bd --- /dev/null +++ b/tests/cases/fourslash/quickInfoSignatureRestParameterFromUnion3.ts @@ -0,0 +1,22 @@ +/// + +//// declare const fn: +//// | ((a: { x: number }, b: { x: number }) => number) +//// | ((...a: { y: number }[]) => number); +//// +//// /**/fn(); + +verify.quickInfoAt( + "", + `const fn: (a: { + x: number; +} & { + y: number; +}, b: { + x: number; +} & { + y: number; +}, ...args: { + y: number; +}[]) => number`, +); diff --git a/tests/cases/fourslash/quickInfoSignatureRestParameterFromUnion4.ts b/tests/cases/fourslash/quickInfoSignatureRestParameterFromUnion4.ts new file mode 100644 index 00000000000..40e1882307e --- /dev/null +++ b/tests/cases/fourslash/quickInfoSignatureRestParameterFromUnion4.ts @@ -0,0 +1,22 @@ +/// + +//// declare const fn: +//// | ((a?: { x: number }, b?: { x: number }) => number) +//// | ((...a: { y: number }[]) => number); +//// +//// /**/fn(); + +verify.quickInfoAt( + "", + `const fn: (a?: { + x: number; +} & { + y: number; +}, b?: { + x: number; +} & { + y: number; +}, ...args: { + y: number; +}[]) => number`, +);