From 55ae4a3cdef498438114557708986980a1a5e7f3 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Wed, 25 Jan 2023 16:52:15 -0800 Subject: [PATCH 1/9] Check @overload sigs against impl sig Check @overload signatures and implementation signatures. checkFunctionOrConstructorSymbolWorker doesn't recognise functions with @overload tags as overloaded because it's using a simple syntactic check based on TS syntax. This PR adds a check for @overload tags as well. --- src/compiler/checker.ts | 14 +++- .../reference/overloadTag1.errors.txt | 41 +++++++++++ tests/baselines/reference/overloadTag1.js | 67 +++++++++++++++++ .../baselines/reference/overloadTag1.symbols | 48 +++++++++++++ tests/baselines/reference/overloadTag1.types | 72 +++++++++++++++++++ tests/cases/conformance/jsdoc/overloadTag1.ts | 32 +++++++++ 6 files changed, 273 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/overloadTag1.errors.txt create mode 100644 tests/baselines/reference/overloadTag1.js create mode 100644 tests/baselines/reference/overloadTag1.symbols create mode 100644 tests/baselines/reference/overloadTag1.types create mode 100644 tests/cases/conformance/jsdoc/overloadTag1.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 4765c1aa33402..7d41cba45a615 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -38583,9 +38583,21 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { lastSeenNonAmbientDeclaration = node as FunctionLikeDeclaration; } } + if (isInJSFile(current) && isFunctionLike(current) && current.jsDoc) { + // TODO: De-duplicate tag check and improve error span + outer: for (const node of current.jsDoc) { + if (node.tags) { + for (const tag of node.tags) { + if (isJSDocOverloadTag(tag)) { + hasOverloads = true; + break outer; + } + } + } + } + } } } - if (multipleConstructorImplementation) { forEach(functionDeclarations, declaration => { error(declaration, Diagnostics.Multiple_constructor_implementations_are_not_allowed); diff --git a/tests/baselines/reference/overloadTag1.errors.txt b/tests/baselines/reference/overloadTag1.errors.txt new file mode 100644 index 0000000000000..f56f1ed24191f --- /dev/null +++ b/tests/baselines/reference/overloadTag1.errors.txt @@ -0,0 +1,41 @@ +tests/cases/conformance/jsdoc/overloadTag1.js(27,1): error TS2769: No overload matches this call. + Overload 1 of 2, '(a: number, b: number): number', gave the following error. + Argument of type 'string' is not assignable to parameter of type 'number'. + Overload 2 of 2, '(a: string, b: boolean): string', gave the following error. + Argument of type 'string' is not assignable to parameter of type 'boolean'. + + +==== tests/cases/conformance/jsdoc/overloadTag1.js (1 errors) ==== + /** + * @overload + * @param {number} a + * @param {number} b + * @returns {number} + */ + /** + * @overload + * @param {string} a + * @param {boolean} b + * @returns {string} + */ + /** + * @param {string | number} a + * @param {string | number} b + * @returns {string | number} + */ + export function overloaded(a,b) { + if (typeof a === "string" && typeof b === "string") { + return a + b; + } else if (typeof a === "number" && typeof b === "number") { + return a + b; + } + throw new Error("Invalid arguments"); + } + overloaded(1,2) + overloaded("zero", "one") + ~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2769: No overload matches this call. +!!! error TS2769: Overload 1 of 2, '(a: number, b: number): number', gave the following error. +!!! error TS2769: Argument of type 'string' is not assignable to parameter of type 'number'. +!!! error TS2769: Overload 2 of 2, '(a: string, b: boolean): string', gave the following error. +!!! error TS2769: Argument of type 'string' is not assignable to parameter of type 'boolean'. \ No newline at end of file diff --git a/tests/baselines/reference/overloadTag1.js b/tests/baselines/reference/overloadTag1.js new file mode 100644 index 0000000000000..139832a12541c --- /dev/null +++ b/tests/baselines/reference/overloadTag1.js @@ -0,0 +1,67 @@ +//// [overloadTag1.js] +/** + * @overload + * @param {number} a + * @param {number} b + * @returns {number} + */ +/** + * @overload + * @param {string} a + * @param {boolean} b + * @returns {string} + */ +/** + * @param {string | number} a + * @param {string | number} b + * @returns {string | number} + */ +export function overloaded(a,b) { + if (typeof a === "string" && typeof b === "string") { + return a + b; + } else if (typeof a === "number" && typeof b === "number") { + return a + b; + } + throw new Error("Invalid arguments"); +} +overloaded(1,2) +overloaded("zero", "one") + +//// [overloadTag1.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.overloaded = void 0; +/** + * @overload + * @param {number} a + * @param {number} b + * @returns {number} + */ +/** + * @overload + * @param {string} a + * @param {boolean} b + * @returns {string} + */ +/** + * @param {string | number} a + * @param {string | number} b + * @returns {string | number} + */ +function overloaded(a, b) { + if (typeof a === "string" && typeof b === "string") { + return a + b; + } + else if (typeof a === "number" && typeof b === "number") { + return a + b; + } + throw new Error("Invalid arguments"); +} +exports.overloaded = overloaded; +overloaded(1, 2); +overloaded("zero", "one"); + + +//// [overloadTag1.d.ts] +export function overloaded(a: number, b: number): number; +export function overloaded(a: string, b: boolean): string; diff --git a/tests/baselines/reference/overloadTag1.symbols b/tests/baselines/reference/overloadTag1.symbols new file mode 100644 index 0000000000000..bd0a10253296b --- /dev/null +++ b/tests/baselines/reference/overloadTag1.symbols @@ -0,0 +1,48 @@ +=== tests/cases/conformance/jsdoc/overloadTag1.js === +/** + * @overload + * @param {number} a + * @param {number} b + * @returns {number} + */ +/** + * @overload + * @param {string} a + * @param {boolean} b + * @returns {string} + */ +/** + * @param {string | number} a + * @param {string | number} b + * @returns {string | number} + */ +export function overloaded(a,b) { +>overloaded : Symbol(overloaded, Decl(overloadTag1.js, 0, 0)) +>a : Symbol(a, Decl(overloadTag1.js, 17, 27)) +>b : Symbol(b, Decl(overloadTag1.js, 17, 29)) + + if (typeof a === "string" && typeof b === "string") { +>a : Symbol(a, Decl(overloadTag1.js, 17, 27)) +>b : Symbol(b, Decl(overloadTag1.js, 17, 29)) + + return a + b; +>a : Symbol(a, Decl(overloadTag1.js, 17, 27)) +>b : Symbol(b, Decl(overloadTag1.js, 17, 29)) + + } else if (typeof a === "number" && typeof b === "number") { +>a : Symbol(a, Decl(overloadTag1.js, 17, 27)) +>b : Symbol(b, Decl(overloadTag1.js, 17, 29)) + + return a + b; +>a : Symbol(a, Decl(overloadTag1.js, 17, 27)) +>b : Symbol(b, Decl(overloadTag1.js, 17, 29)) + } + throw new Error("Invalid arguments"); +>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +} +overloaded(1,2) +>overloaded : Symbol(overloaded, Decl(overloadTag1.js, 0, 0)) + +overloaded("zero", "one") +>overloaded : Symbol(overloaded, Decl(overloadTag1.js, 0, 0)) + diff --git a/tests/baselines/reference/overloadTag1.types b/tests/baselines/reference/overloadTag1.types new file mode 100644 index 0000000000000..32c2d55cbf91d --- /dev/null +++ b/tests/baselines/reference/overloadTag1.types @@ -0,0 +1,72 @@ +=== tests/cases/conformance/jsdoc/overloadTag1.js === +/** + * @overload + * @param {number} a + * @param {number} b + * @returns {number} + */ +/** + * @overload + * @param {string} a + * @param {boolean} b + * @returns {string} + */ +/** + * @param {string | number} a + * @param {string | number} b + * @returns {string | number} + */ +export function overloaded(a,b) { +>overloaded : { (a: number, b: number): number; (a: string, b: boolean): string; } +>a : string | number +>b : string | number + + if (typeof a === "string" && typeof b === "string") { +>typeof a === "string" && typeof b === "string" : boolean +>typeof a === "string" : boolean +>typeof a : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" +>a : string | number +>"string" : "string" +>typeof b === "string" : boolean +>typeof b : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" +>b : string | number +>"string" : "string" + + return a + b; +>a + b : string +>a : string +>b : string + + } else if (typeof a === "number" && typeof b === "number") { +>typeof a === "number" && typeof b === "number" : boolean +>typeof a === "number" : boolean +>typeof a : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" +>a : string | number +>"number" : "number" +>typeof b === "number" : boolean +>typeof b : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" +>b : string | number +>"number" : "number" + + return a + b; +>a + b : number +>a : number +>b : number + } + throw new Error("Invalid arguments"); +>new Error("Invalid arguments") : Error +>Error : ErrorConstructor +>"Invalid arguments" : "Invalid arguments" +} +overloaded(1,2) +>overloaded(1,2) : number +>overloaded : { (a: number, b: number): number; (a: string, b: boolean): string; } +>1 : 1 +>2 : 2 + +overloaded("zero", "one") +>overloaded("zero", "one") : never +>overloaded : { (a: number, b: number): number; (a: string, b: boolean): string; } +>"zero" : "zero" +>"one" : "one" + diff --git a/tests/cases/conformance/jsdoc/overloadTag1.ts b/tests/cases/conformance/jsdoc/overloadTag1.ts new file mode 100644 index 0000000000000..447b9267f3012 --- /dev/null +++ b/tests/cases/conformance/jsdoc/overloadTag1.ts @@ -0,0 +1,32 @@ +// @checkJs: true +// @allowJs: true +// @outdir: foo +// @declaration: true +// @filename: overloadTag1.js +/** + * @overload + * @param {number} a + * @param {number} b + * @returns {number} + */ +/** + * @overload + * @param {string} a + * @param {boolean} b + * @returns {string} + */ +/** + * @param {string | number} a + * @param {string | number} b + * @returns {string | number} + */ +export function overloaded(a,b) { + if (typeof a === "string" && typeof b === "string") { + return a + b; + } else if (typeof a === "number" && typeof b === "number") { + return a + b; + } + throw new Error("Invalid arguments"); +} +overloaded(1,2) +overloaded("zero", "one") \ No newline at end of file From e796e7b4cdf1517efb5c62a1b961e875e68b84c1 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Fri, 27 Jan 2023 16:27:28 -0800 Subject: [PATCH 2/9] Check @overload tag against its implementation Also, make @overload work like other jsdoc tags: only the last jsdoc tag before a declaration is used. That means all overload tags need to be in one tag: ```js /** * @overload * @return {number} * * @overload * @return {string} */ ``` function f() { return "1" } This no longer works: ```js /** * @overload * @return {number} */ /** * @overload * @return {string} */ function f() { return "2" } ``` Fixes #51234 --- src/compiler/checker.ts | 33 +++++------- src/compiler/utilitiesPublic.ts | 6 ++- .../jsFileAlternativeUseOfOverloadTag.js | 7 +-- .../jsFileAlternativeUseOfOverloadTag.types | 30 +++++------ .../reference/jsFileFunctionOverloads.js | 45 ++++++++++++++-- .../reference/jsFileFunctionOverloads.types | 4 +- .../reference/jsFileMethodOverloads.js | 33 ++++++++++-- .../reference/jsFileMethodOverloads.types | 4 +- .../reference/overloadTag1.errors.txt | 45 +++++++++++++--- tests/baselines/reference/overloadTag1.js | 53 +++++++++++++++---- .../baselines/reference/overloadTag1.symbols | 52 +++++++++++++----- tests/baselines/reference/overloadTag1.types | 39 ++++++++++++-- tests/cases/conformance/jsdoc/overloadTag1.ts | 25 +++++++-- 13 files changed, 283 insertions(+), 93 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 7d41cba45a615..bd395f1f80406 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -230,6 +230,7 @@ import { getAliasDeclarationFromName, getAllAccessorDeclarations, getAllJSDocTags, + getAllJSDocTagsOfKind, getAllowSyntheticDefaultImports, getAncestor, getAssignedExpandoInitializer, @@ -279,6 +280,7 @@ import { getExternalModuleRequireArgument, getFirstConstructorWithBody, getFirstIdentifier, + getFirstJSDocTag, getFunctionFlags, getHostSignatureFromJSDoc, getIdentifierGeneratedImportReference, @@ -745,6 +747,7 @@ import { JSDocMemberName, JSDocNullableType, JSDocOptionalType, + JSDocOverloadTag, JSDocParameterTag, JSDocPrivateTag, JSDocPropertyLikeTag, @@ -14442,15 +14445,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } if (isInJSFile(decl) && decl.jsDoc) { let hasJSDocOverloads = false; - for (const node of decl.jsDoc) { - if (node.tags) { - for (const tag of node.tags) { - if (isJSDocOverloadTag(tag)) { - result.push(getSignatureFromDeclaration(tag.typeExpression)); - hasJSDocOverloads = true; - } - } - } + for (const tag of getAllJSDocTagsOfKind(decl, SyntaxKind.JSDocOverloadTag)) { + result.push(getSignatureFromDeclaration((tag as JSDocOverloadTag).typeExpression)); + hasJSDocOverloads = true; } if (hasJSDocOverloads) { continue; @@ -38584,20 +38581,13 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } } if (isInJSFile(current) && isFunctionLike(current) && current.jsDoc) { - // TODO: De-duplicate tag check and improve error span - outer: for (const node of current.jsDoc) { - if (node.tags) { - for (const tag of node.tags) { - if (isJSDocOverloadTag(tag)) { - hasOverloads = true; - break outer; - } - } - } + if (getFirstJSDocTag(current, isJSDocOverloadTag)) { + hasOverloads = true; } } } } + if (multipleConstructorImplementation) { forEach(functionDeclarations, declaration => { error(declaration, Diagnostics.Multiple_constructor_implementations_are_not_allowed); @@ -38646,8 +38636,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const bodySignature = getSignatureFromDeclaration(bodyDeclaration); for (const signature of signatures) { if (!isImplementationCompatibleWithOverload(bodySignature, signature)) { + const errorNode = signature.declaration && isJSDocSignature(signature.declaration) + ? (signature.declaration.parent as JSDocOverloadTag | JSDocCallbackTag).tagName + : signature.declaration; addRelatedInfo( - error(signature.declaration, Diagnostics.This_overload_signature_is_not_compatible_with_its_implementation_signature), + error(errorNode, Diagnostics.This_overload_signature_is_not_compatible_with_its_implementation_signature), createDiagnosticForNode(bodyDeclaration, Diagnostics.The_implementation_signature_is_declared_here) ); break; diff --git a/src/compiler/utilitiesPublic.ts b/src/compiler/utilitiesPublic.ts index 8a11f5f0f97f4..bd34c0c5aa3f8 100644 --- a/src/compiler/utilitiesPublic.ts +++ b/src/compiler/utilitiesPublic.ts @@ -1205,8 +1205,10 @@ export function getJSDocTagsNoCache(node: Node): readonly JSDocTag[] { return getJSDocTagsWorker(node, /*noCache*/ true); } -/** Get the first JSDoc tag of a specified kind, or undefined if not present. */ -function getFirstJSDocTag(node: Node, predicate: (tag: JSDocTag) => tag is T, noCache?: boolean): T | undefined { +/** @internal + * Get the first JSDoc tag of a specified kind, or undefined if not present. + */ +export function getFirstJSDocTag(node: Node, predicate: (tag: JSDocTag) => tag is T, noCache?: boolean): T | undefined { return find(getJSDocTagsWorker(node, noCache), predicate); } diff --git a/tests/baselines/reference/jsFileAlternativeUseOfOverloadTag.js b/tests/baselines/reference/jsFileAlternativeUseOfOverloadTag.js index e34b9c77c5379..3f5e3f5ad5cf2 100644 --- a/tests/baselines/reference/jsFileAlternativeUseOfOverloadTag.js +++ b/tests/baselines/reference/jsFileAlternativeUseOfOverloadTag.js @@ -105,14 +105,15 @@ var example3 = { //// [jsFileAlternativeUseOfOverloadTag.d.ts] declare namespace example1 { - function constructor(value: any, options: any): void; + function constructor(value: any): any; } declare namespace example2 { - export function constructor_1(): void; + export function constructor_1(value: any, secretAccessKey: any, sessionToken: any): any; + export function constructor_1(): any; export { constructor_1 as constructor }; } declare namespace example3 { - function evaluate(options: any, callback: any): void; + function evaluate(): any; } /** * function (error, result) diff --git a/tests/baselines/reference/jsFileAlternativeUseOfOverloadTag.types b/tests/baselines/reference/jsFileAlternativeUseOfOverloadTag.types index aa606c5ade669..4bc1b1db7d38c 100644 --- a/tests/baselines/reference/jsFileAlternativeUseOfOverloadTag.types +++ b/tests/baselines/reference/jsFileAlternativeUseOfOverloadTag.types @@ -4,8 +4,8 @@ // trying to make sure that our changes do not result in any crashes here. const example1 = { ->example1 : { constructor: (value: any, options: any) => void; } ->{ /** * @overload Example1(value) * Creates Example1 * @param value [String] */ constructor: function Example1(value, options) {},} : { constructor: (value: any, options: any) => void; } +>example1 : { constructor: (value: any) => any; } +>{ /** * @overload Example1(value) * Creates Example1 * @param value [String] */ constructor: function Example1(value, options) {},} : { constructor: (value: any) => any; } /** * @overload Example1(value) @@ -13,17 +13,17 @@ const example1 = { * @param value [String] */ constructor: function Example1(value, options) {}, ->constructor : (value: any, options: any) => void ->function Example1(value, options) {} : (value: any, options: any) => void ->Example1 : (value: any, options: any) => void +>constructor : (value: any) => any +>function Example1(value, options) {} : (value: any) => any +>Example1 : (value: any) => any >value : any >options : any }; const example2 = { ->example2 : { constructor: () => void; } ->{ /** * Example 2 * * @overload Example2(value) * Creates Example2 * @param value [String] * @param secretAccessKey [String] * @param sessionToken [String] * @example Creates with string value * const example = new Example(''); * @overload Example2(options) * Creates Example2 * @option options value [String] * @example Creates with options object * const example = new Example2({ * value: '', * }); */ constructor: function Example2() {},} : { constructor: () => void; } +>example2 : { constructor: { (value: any, secretAccessKey: any, sessionToken: any): any; (): any; }; } +>{ /** * Example 2 * * @overload Example2(value) * Creates Example2 * @param value [String] * @param secretAccessKey [String] * @param sessionToken [String] * @example Creates with string value * const example = new Example(''); * @overload Example2(options) * Creates Example2 * @option options value [String] * @example Creates with options object * const example = new Example2({ * value: '', * }); */ constructor: function Example2() {},} : { constructor: { (value: any, secretAccessKey: any, sessionToken: any): any; (): any; }; } /** * Example 2 @@ -44,15 +44,15 @@ const example2 = { * }); */ constructor: function Example2() {}, ->constructor : () => void ->function Example2() {} : () => void ->Example2 : () => void +>constructor : { (value: any, secretAccessKey: any, sessionToken: any): any; (): any; } +>function Example2() {} : { (value: any, secretAccessKey: any, sessionToken: any): any; (): any; } +>Example2 : { (value: any, secretAccessKey: any, sessionToken: any): any; (): any; } }; const example3 = { ->example3 : { evaluate: (options: any, callback: any) => void; } ->{ /** * @overload evaluate(options = {}, [callback]) * Evaluate something * @note Something interesting * @param options [map] * @return [string] returns evaluation result * @return [null] returns nothing if callback provided * @callback callback function (error, result) * If callback is provided it will be called with evaluation result * @param error [Error] * @param result [String] * @see callback */ evaluate: function evaluate(options, callback) {},} : { evaluate: (options: any, callback: any) => void; } +>example3 : { evaluate: () => any; } +>{ /** * @overload evaluate(options = {}, [callback]) * Evaluate something * @note Something interesting * @param options [map] * @return [string] returns evaluation result * @return [null] returns nothing if callback provided * @callback callback function (error, result) * If callback is provided it will be called with evaluation result * @param error [Error] * @param result [String] * @see callback */ evaluate: function evaluate(options, callback) {},} : { evaluate: () => any; } /** * @overload evaluate(options = {}, [callback]) @@ -68,9 +68,9 @@ const example3 = { * @see callback */ evaluate: function evaluate(options, callback) {}, ->evaluate : (options: any, callback: any) => void ->function evaluate(options, callback) {} : (options: any, callback: any) => void ->evaluate : (options: any, callback: any) => void +>evaluate : () => any +>function evaluate(options, callback) {} : () => any +>evaluate : () => any >options : any >callback : any diff --git a/tests/baselines/reference/jsFileFunctionOverloads.js b/tests/baselines/reference/jsFileFunctionOverloads.js index a49b87851b0d9..0b1fc664edf43 100644 --- a/tests/baselines/reference/jsFileFunctionOverloads.js +++ b/tests/baselines/reference/jsFileFunctionOverloads.js @@ -118,11 +118,46 @@ function flatMap(array, iterable) { //// [jsFileFunctionOverloads.d.ts] -declare function getTypeName(x: number): 'number'; -declare function getTypeName(x: string): 'string'; -declare function getTypeName(x: boolean): 'boolean'; -declare function flatMap(array: T[], iterable: (x: T) => U[]): U[]; -declare function flatMap(array: T[][]): T[]; +/** + * @overload + * @param {number} x + * @returns {'number'} + */ +/** + * @overload + * @param {string} x + * @returns {'string'} + */ +/** + * @overload + * @param {boolean} x + * @returns {'boolean'} + */ +/** + * @param {unknown} x + * @returns {string} + */ +declare function getTypeName(x: unknown): string; +/** + * @template T + * @template U + * @overload + * @param {T[]} array + * @param {(x: T) => U[]} iterable + * @returns {U[]} + */ +/** + * @template T + * @overload + * @param {T[][]} array + * @returns {T[]} + */ +/** + * @param {unknown[]} array + * @param {(x: unknown) => unknown} iterable + * @returns {unknown[]} + */ +declare function flatMap(array: unknown[], iterable?: (x: unknown) => unknown): unknown[]; /** * @template T * @param {T} x diff --git a/tests/baselines/reference/jsFileFunctionOverloads.types b/tests/baselines/reference/jsFileFunctionOverloads.types index a22495f41b18d..a8154cab15bc9 100644 --- a/tests/baselines/reference/jsFileFunctionOverloads.types +++ b/tests/baselines/reference/jsFileFunctionOverloads.types @@ -19,7 +19,7 @@ * @returns {string} */ function getTypeName(x) { ->getTypeName : { (x: number): 'number'; (x: string): 'string'; (x: boolean): 'boolean'; } +>getTypeName : (x: unknown) => string >x : unknown return typeof x; @@ -58,7 +58,7 @@ const identity = x => x; * @returns {unknown[]} */ function flatMap(array, iterable = identity) { ->flatMap : { (array: T[], iterable: (x: T) => U[]): U[]; (array: T[][]): T[]; } +>flatMap : (array: unknown[], iterable?: (x: unknown) => unknown) => unknown[] >array : unknown[] >iterable : (x: unknown) => unknown >identity : (x: T) => T diff --git a/tests/baselines/reference/jsFileMethodOverloads.js b/tests/baselines/reference/jsFileMethodOverloads.js index c911e0bd8ca88..d48f81817567b 100644 --- a/tests/baselines/reference/jsFileMethodOverloads.js +++ b/tests/baselines/reference/jsFileMethodOverloads.js @@ -105,8 +105,33 @@ declare class Example { */ constructor(value: T); value: T; - getTypeName(this: Example): 'number'; - getTypeName(this: Example): 'string'; - transform(fn: (y: T) => U): U; - transform(): T; + /** + * @overload + * @param {Example} this + * @returns {'number'} + */ + /** + * @overload + * @param {Example} this + * @returns {'string'} + */ + /** + * @returns {string} + */ + getTypeName(): string; + /** + * @template U + * @overload + * @param {(y: T) => U} fn + * @returns {U} + */ + /** + * @overload + * @returns {T} + */ + /** + * @param {(y: T) => unknown} [fn] + * @returns {unknown} + */ + transform(fn?: (y: T) => unknown): unknown; } diff --git a/tests/baselines/reference/jsFileMethodOverloads.types b/tests/baselines/reference/jsFileMethodOverloads.types index 7cce51446af70..ad14e1e2f0880 100644 --- a/tests/baselines/reference/jsFileMethodOverloads.types +++ b/tests/baselines/reference/jsFileMethodOverloads.types @@ -33,7 +33,7 @@ * @returns {string} */ getTypeName() { ->getTypeName : { (this: Example): 'number'; (this: Example): 'string'; } +>getTypeName : () => string return typeof this.value; >typeof this.value : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" @@ -57,7 +57,7 @@ * @returns {unknown} */ transform(fn) { ->transform : { (fn: (y: T) => U): U; (): T; } +>transform : (fn?: (y: T) => unknown) => unknown >fn : (y: T) => unknown return fn ? fn(this.value) : this.value; diff --git a/tests/baselines/reference/overloadTag1.errors.txt b/tests/baselines/reference/overloadTag1.errors.txt index f56f1ed24191f..c25d1af70c1fd 100644 --- a/tests/baselines/reference/overloadTag1.errors.txt +++ b/tests/baselines/reference/overloadTag1.errors.txt @@ -1,24 +1,31 @@ -tests/cases/conformance/jsdoc/overloadTag1.js(27,1): error TS2769: No overload matches this call. +tests/cases/conformance/jsdoc/overloadTag1.js(7,5): error TS2394: This overload signature is not compatible with its implementation signature. +tests/cases/conformance/jsdoc/overloadTag1.js(25,1): error TS2769: No overload matches this call. + Overload 1 of 2, '(a: number, b: number): number', gave the following error. + Argument of type 'string' is not assignable to parameter of type 'number'. + Overload 2 of 2, '(a: string, b: boolean): string', gave the following error. + Argument of type 'string' is not assignable to parameter of type 'boolean'. +tests/cases/conformance/jsdoc/overloadTag1.js(42,1): error TS2769: No overload matches this call. Overload 1 of 2, '(a: number, b: number): number', gave the following error. Argument of type 'string' is not assignable to parameter of type 'number'. Overload 2 of 2, '(a: string, b: boolean): string', gave the following error. Argument of type 'string' is not assignable to parameter of type 'boolean'. -==== tests/cases/conformance/jsdoc/overloadTag1.js (1 errors) ==== +==== tests/cases/conformance/jsdoc/overloadTag1.js (3 errors) ==== /** * @overload * @param {number} a * @param {number} b * @returns {number} - */ - /** + * * @overload + ~~~~~~~~ +!!! error TS2394: This overload signature is not compatible with its implementation signature. +!!! related TS2750 tests/cases/conformance/jsdoc/overloadTag1.js:16:17: The implementation signature is declared here. * @param {string} a * @param {boolean} b * @returns {string} - */ - /** + * * @param {string | number} a * @param {string | number} b * @returns {string | number} @@ -38,4 +45,28 @@ tests/cases/conformance/jsdoc/overloadTag1.js(27,1): error TS2769: No overload m !!! error TS2769: Overload 1 of 2, '(a: number, b: number): number', gave the following error. !!! error TS2769: Argument of type 'string' is not assignable to parameter of type 'number'. !!! error TS2769: Overload 2 of 2, '(a: string, b: boolean): string', gave the following error. -!!! error TS2769: Argument of type 'string' is not assignable to parameter of type 'boolean'. \ No newline at end of file +!!! error TS2769: Argument of type 'string' is not assignable to parameter of type 'boolean'. + + /** + * @overload + * @param {number} a + * @param {number} b + * @returns {number} + * + * @overload + * @param {string} a + * @param {boolean} b + * @returns {string} + */ + export function uncheckedInternally(a, b) { + return a + b; + } + uncheckedInternally(1,2) + uncheckedInternally("zero", "one") + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2769: No overload matches this call. +!!! error TS2769: Overload 1 of 2, '(a: number, b: number): number', gave the following error. +!!! error TS2769: Argument of type 'string' is not assignable to parameter of type 'number'. +!!! error TS2769: Overload 2 of 2, '(a: string, b: boolean): string', gave the following error. +!!! error TS2769: Argument of type 'string' is not assignable to parameter of type 'boolean'. + \ No newline at end of file diff --git a/tests/baselines/reference/overloadTag1.js b/tests/baselines/reference/overloadTag1.js index 139832a12541c..667ccc69b03b7 100644 --- a/tests/baselines/reference/overloadTag1.js +++ b/tests/baselines/reference/overloadTag1.js @@ -4,14 +4,12 @@ * @param {number} a * @param {number} b * @returns {number} - */ -/** + * * @overload * @param {string} a * @param {boolean} b * @returns {string} - */ -/** + * * @param {string | number} a * @param {string | number} b * @returns {string | number} @@ -25,25 +23,41 @@ export function overloaded(a,b) { throw new Error("Invalid arguments"); } overloaded(1,2) -overloaded("zero", "one") +overloaded("zero", "one") + +/** + * @overload + * @param {number} a + * @param {number} b + * @returns {number} + * + * @overload + * @param {string} a + * @param {boolean} b + * @returns {string} + */ +export function uncheckedInternally(a, b) { + return a + b; +} +uncheckedInternally(1,2) +uncheckedInternally("zero", "one") + //// [overloadTag1.js] "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -exports.overloaded = void 0; +exports.uncheckedInternally = exports.overloaded = void 0; /** * @overload * @param {number} a * @param {number} b * @returns {number} - */ -/** + * * @overload * @param {string} a * @param {boolean} b * @returns {string} - */ -/** + * * @param {string | number} a * @param {string | number} b * @returns {string | number} @@ -60,8 +74,27 @@ function overloaded(a, b) { exports.overloaded = overloaded; overloaded(1, 2); overloaded("zero", "one"); +/** + * @overload + * @param {number} a + * @param {number} b + * @returns {number} + * + * @overload + * @param {string} a + * @param {boolean} b + * @returns {string} + */ +function uncheckedInternally(a, b) { + return a + b; +} +exports.uncheckedInternally = uncheckedInternally; +uncheckedInternally(1, 2); +uncheckedInternally("zero", "one"); //// [overloadTag1.d.ts] export function overloaded(a: number, b: number): number; export function overloaded(a: string, b: boolean): string; +export function uncheckedInternally(a: number, b: number): number; +export function uncheckedInternally(a: string, b: boolean): string; diff --git a/tests/baselines/reference/overloadTag1.symbols b/tests/baselines/reference/overloadTag1.symbols index bd0a10253296b..565286ccb6d77 100644 --- a/tests/baselines/reference/overloadTag1.symbols +++ b/tests/baselines/reference/overloadTag1.symbols @@ -4,38 +4,36 @@ * @param {number} a * @param {number} b * @returns {number} - */ -/** + * * @overload * @param {string} a * @param {boolean} b * @returns {string} - */ -/** + * * @param {string | number} a * @param {string | number} b * @returns {string | number} */ export function overloaded(a,b) { >overloaded : Symbol(overloaded, Decl(overloadTag1.js, 0, 0)) ->a : Symbol(a, Decl(overloadTag1.js, 17, 27)) ->b : Symbol(b, Decl(overloadTag1.js, 17, 29)) +>a : Symbol(a, Decl(overloadTag1.js, 15, 27)) +>b : Symbol(b, Decl(overloadTag1.js, 15, 29)) if (typeof a === "string" && typeof b === "string") { ->a : Symbol(a, Decl(overloadTag1.js, 17, 27)) ->b : Symbol(b, Decl(overloadTag1.js, 17, 29)) +>a : Symbol(a, Decl(overloadTag1.js, 15, 27)) +>b : Symbol(b, Decl(overloadTag1.js, 15, 29)) return a + b; ->a : Symbol(a, Decl(overloadTag1.js, 17, 27)) ->b : Symbol(b, Decl(overloadTag1.js, 17, 29)) +>a : Symbol(a, Decl(overloadTag1.js, 15, 27)) +>b : Symbol(b, Decl(overloadTag1.js, 15, 29)) } else if (typeof a === "number" && typeof b === "number") { ->a : Symbol(a, Decl(overloadTag1.js, 17, 27)) ->b : Symbol(b, Decl(overloadTag1.js, 17, 29)) +>a : Symbol(a, Decl(overloadTag1.js, 15, 27)) +>b : Symbol(b, Decl(overloadTag1.js, 15, 29)) return a + b; ->a : Symbol(a, Decl(overloadTag1.js, 17, 27)) ->b : Symbol(b, Decl(overloadTag1.js, 17, 29)) +>a : Symbol(a, Decl(overloadTag1.js, 15, 27)) +>b : Symbol(b, Decl(overloadTag1.js, 15, 29)) } throw new Error("Invalid arguments"); >Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) @@ -46,3 +44,29 @@ overloaded(1,2) overloaded("zero", "one") >overloaded : Symbol(overloaded, Decl(overloadTag1.js, 0, 0)) +/** + * @overload + * @param {number} a + * @param {number} b + * @returns {number} + * + * @overload + * @param {string} a + * @param {boolean} b + * @returns {string} + */ +export function uncheckedInternally(a, b) { +>uncheckedInternally : Symbol(uncheckedInternally, Decl(overloadTag1.js, 24, 25)) +>a : Symbol(a, Decl(overloadTag1.js, 37, 36)) +>b : Symbol(b, Decl(overloadTag1.js, 37, 38)) + + return a + b; +>a : Symbol(a, Decl(overloadTag1.js, 37, 36)) +>b : Symbol(b, Decl(overloadTag1.js, 37, 38)) +} +uncheckedInternally(1,2) +>uncheckedInternally : Symbol(uncheckedInternally, Decl(overloadTag1.js, 24, 25)) + +uncheckedInternally("zero", "one") +>uncheckedInternally : Symbol(uncheckedInternally, Decl(overloadTag1.js, 24, 25)) + diff --git a/tests/baselines/reference/overloadTag1.types b/tests/baselines/reference/overloadTag1.types index 32c2d55cbf91d..a1cc96d9a4657 100644 --- a/tests/baselines/reference/overloadTag1.types +++ b/tests/baselines/reference/overloadTag1.types @@ -4,14 +4,12 @@ * @param {number} a * @param {number} b * @returns {number} - */ -/** + * * @overload * @param {string} a * @param {boolean} b * @returns {string} - */ -/** + * * @param {string | number} a * @param {string | number} b * @returns {string | number} @@ -70,3 +68,36 @@ overloaded("zero", "one") >"zero" : "zero" >"one" : "one" +/** + * @overload + * @param {number} a + * @param {number} b + * @returns {number} + * + * @overload + * @param {string} a + * @param {boolean} b + * @returns {string} + */ +export function uncheckedInternally(a, b) { +>uncheckedInternally : { (a: number, b: number): number; (a: string, b: boolean): string; } +>a : any +>b : any + + return a + b; +>a + b : any +>a : any +>b : any +} +uncheckedInternally(1,2) +>uncheckedInternally(1,2) : number +>uncheckedInternally : { (a: number, b: number): number; (a: string, b: boolean): string; } +>1 : 1 +>2 : 2 + +uncheckedInternally("zero", "one") +>uncheckedInternally("zero", "one") : never +>uncheckedInternally : { (a: number, b: number): number; (a: string, b: boolean): string; } +>"zero" : "zero" +>"one" : "one" + diff --git a/tests/cases/conformance/jsdoc/overloadTag1.ts b/tests/cases/conformance/jsdoc/overloadTag1.ts index 447b9267f3012..0d542a13b5bc2 100644 --- a/tests/cases/conformance/jsdoc/overloadTag1.ts +++ b/tests/cases/conformance/jsdoc/overloadTag1.ts @@ -8,14 +8,12 @@ * @param {number} a * @param {number} b * @returns {number} - */ -/** + * * @overload * @param {string} a * @param {boolean} b * @returns {string} - */ -/** + * * @param {string | number} a * @param {string | number} b * @returns {string | number} @@ -29,4 +27,21 @@ export function overloaded(a,b) { throw new Error("Invalid arguments"); } overloaded(1,2) -overloaded("zero", "one") \ No newline at end of file +overloaded("zero", "one") + +/** + * @overload + * @param {number} a + * @param {number} b + * @returns {number} + * + * @overload + * @param {string} a + * @param {boolean} b + * @returns {string} + */ +export function uncheckedInternally(a, b) { + return a + b; +} +uncheckedInternally(1,2) +uncheckedInternally("zero", "one") From 67d1dc81b53833ed308f7ecfff173e4b21986aa6 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Thu, 2 Feb 2023 09:08:12 -0800 Subject: [PATCH 3/9] fix spacing --- src/compiler/checker.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c9bf96ef08ad6..12aa0c2e748d9 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -14454,7 +14454,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } if (isInJSFile(decl) && decl.jsDoc) { let hasJSDocOverloads = false; - for (const node of decl.jsDoc) { + for (const node of decl.jsDoc) { if (node.tags) { for (const tag of node.tags) { if (isJSDocOverloadTag(tag)) { @@ -14466,7 +14466,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } } } - } + } if (hasJSDocOverloads) { continue; } From 3ad2444a2123444d02494ac624f22db2e7a9899e Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Thu, 2 Feb 2023 09:27:58 -0800 Subject: [PATCH 4/9] remove extremely unused imports --- src/compiler/checker.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 12aa0c2e748d9..554a4dfac1e37 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -230,7 +230,6 @@ import { getAliasDeclarationFromName, getAllAccessorDeclarations, getAllJSDocTags, - getAllJSDocTagsOfKind, getAllowSyntheticDefaultImports, getAncestor, getAssignedExpandoInitializer, @@ -280,7 +279,6 @@ import { getExternalModuleRequireArgument, getFirstConstructorWithBody, getFirstIdentifier, - getFirstJSDocTag, getFunctionFlags, getHostSignatureFromJSDoc, getIdentifierGeneratedImportReference, From 40074ad6951ffb6f9a6f3e9bafd012519e4b11ce Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Thu, 2 Feb 2023 09:29:46 -0800 Subject: [PATCH 5/9] revert now-unneeded diff --- src/compiler/checker.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 554a4dfac1e37..fed4bffa0b2ad 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -14456,10 +14456,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (node.tags) { for (const tag of node.tags) { if (isJSDocOverloadTag(tag)) { - if (tag.typeExpression.type === undefined) { - reportImplicitAny(tag.typeExpression, anyType); + const jsDocSignature = tag.typeExpression; + if (jsDocSignature.type === undefined) { + reportImplicitAny(jsDocSignature, anyType); } - result.push(getSignatureFromDeclaration(tag.typeExpression)); + result.push(getSignatureFromDeclaration(jsDocSignature)); hasJSDocOverloads = true; } } From 808739776ed1ddb75b578d4cdc764a4209043d78 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Thu, 2 Feb 2023 09:30:44 -0800 Subject: [PATCH 6/9] remove more unneeded diff --- src/compiler/utilitiesPublic.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/utilitiesPublic.ts b/src/compiler/utilitiesPublic.ts index bd34c0c5aa3f8..0f56083b17850 100644 --- a/src/compiler/utilitiesPublic.ts +++ b/src/compiler/utilitiesPublic.ts @@ -1205,7 +1205,7 @@ export function getJSDocTagsNoCache(node: Node): readonly JSDocTag[] { return getJSDocTagsWorker(node, /*noCache*/ true); } -/** @internal +/** * Get the first JSDoc tag of a specified kind, or undefined if not present. */ export function getFirstJSDocTag(node: Node, predicate: (tag: JSDocTag) => tag is T, noCache?: boolean): T | undefined { From 97ce6f0a94553b3d8a06d36e81653350d0b9f76e Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Thu, 2 Feb 2023 09:31:17 -0800 Subject: [PATCH 7/9] no, actually remove it --- src/compiler/utilitiesPublic.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/compiler/utilitiesPublic.ts b/src/compiler/utilitiesPublic.ts index 0f56083b17850..6ae32b4cc1008 100644 --- a/src/compiler/utilitiesPublic.ts +++ b/src/compiler/utilitiesPublic.ts @@ -1205,9 +1205,7 @@ export function getJSDocTagsNoCache(node: Node): readonly JSDocTag[] { return getJSDocTagsWorker(node, /*noCache*/ true); } -/** - * Get the first JSDoc tag of a specified kind, or undefined if not present. - */ +/** Get the first JSDoc tag of a specified kind, or undefined if not present. */ export function getFirstJSDocTag(node: Node, predicate: (tag: JSDocTag) => tag is T, noCache?: boolean): T | undefined { return find(getJSDocTagsWorker(node, noCache), predicate); } From 2d6f290683bb5db93ec891902033750f04f23b8a Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Thu, 2 Feb 2023 09:31:42 -0800 Subject: [PATCH 8/9] lol@remove --- src/compiler/utilitiesPublic.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/utilitiesPublic.ts b/src/compiler/utilitiesPublic.ts index 6ae32b4cc1008..8a11f5f0f97f4 100644 --- a/src/compiler/utilitiesPublic.ts +++ b/src/compiler/utilitiesPublic.ts @@ -1206,7 +1206,7 @@ export function getJSDocTagsNoCache(node: Node): readonly JSDocTag[] { } /** Get the first JSDoc tag of a specified kind, or undefined if not present. */ -export function getFirstJSDocTag(node: Node, predicate: (tag: JSDocTag) => tag is T, noCache?: boolean): T | undefined { +function getFirstJSDocTag(node: Node, predicate: (tag: JSDocTag) => tag is T, noCache?: boolean): T | undefined { return find(getJSDocTagsWorker(node, noCache), predicate); } From 6772751d435ed3930b3f96fb1c8913b0e790bbfe Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Thu, 2 Feb 2023 09:44:36 -0800 Subject: [PATCH 9/9] better return type tests --- .../reference/overloadTag1.errors.txt | 11 +++++---- tests/baselines/reference/overloadTag1.js | 10 ++++---- .../baselines/reference/overloadTag1.symbols | 24 ++++++++++++------- tests/baselines/reference/overloadTag1.types | 13 ++++++++-- tests/cases/conformance/jsdoc/overloadTag1.ts | 5 ++-- 5 files changed, 41 insertions(+), 22 deletions(-) diff --git a/tests/baselines/reference/overloadTag1.errors.txt b/tests/baselines/reference/overloadTag1.errors.txt index c25d1af70c1fd..faccaf62d16c9 100644 --- a/tests/baselines/reference/overloadTag1.errors.txt +++ b/tests/baselines/reference/overloadTag1.errors.txt @@ -1,10 +1,10 @@ tests/cases/conformance/jsdoc/overloadTag1.js(7,5): error TS2394: This overload signature is not compatible with its implementation signature. -tests/cases/conformance/jsdoc/overloadTag1.js(25,1): error TS2769: No overload matches this call. +tests/cases/conformance/jsdoc/overloadTag1.js(25,10): error TS2769: No overload matches this call. Overload 1 of 2, '(a: number, b: number): number', gave the following error. Argument of type 'string' is not assignable to parameter of type 'number'. Overload 2 of 2, '(a: string, b: boolean): string', gave the following error. Argument of type 'string' is not assignable to parameter of type 'boolean'. -tests/cases/conformance/jsdoc/overloadTag1.js(42,1): error TS2769: No overload matches this call. +tests/cases/conformance/jsdoc/overloadTag1.js(43,1): error TS2769: No overload matches this call. Overload 1 of 2, '(a: number, b: number): number', gave the following error. Argument of type 'string' is not assignable to parameter of type 'number'. Overload 2 of 2, '(a: string, b: boolean): string', gave the following error. @@ -38,14 +38,15 @@ tests/cases/conformance/jsdoc/overloadTag1.js(42,1): error TS2769: No overload m } throw new Error("Invalid arguments"); } - overloaded(1,2) - overloaded("zero", "one") - ~~~~~~~~~~~~~~~~~~~~~~~~~ + var o1 = overloaded(1,2) + var o2 = overloaded("zero", "one") + ~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2769: No overload matches this call. !!! error TS2769: Overload 1 of 2, '(a: number, b: number): number', gave the following error. !!! error TS2769: Argument of type 'string' is not assignable to parameter of type 'number'. !!! error TS2769: Overload 2 of 2, '(a: string, b: boolean): string', gave the following error. !!! error TS2769: Argument of type 'string' is not assignable to parameter of type 'boolean'. + var o3 = overloaded("a",false) /** * @overload diff --git a/tests/baselines/reference/overloadTag1.js b/tests/baselines/reference/overloadTag1.js index 667ccc69b03b7..ddd5b29778b6e 100644 --- a/tests/baselines/reference/overloadTag1.js +++ b/tests/baselines/reference/overloadTag1.js @@ -22,8 +22,9 @@ export function overloaded(a,b) { } throw new Error("Invalid arguments"); } -overloaded(1,2) -overloaded("zero", "one") +var o1 = overloaded(1,2) +var o2 = overloaded("zero", "one") +var o3 = overloaded("a",false) /** * @overload @@ -72,8 +73,9 @@ function overloaded(a, b) { throw new Error("Invalid arguments"); } exports.overloaded = overloaded; -overloaded(1, 2); -overloaded("zero", "one"); +var o1 = overloaded(1, 2); +var o2 = overloaded("zero", "one"); +var o3 = overloaded("a", false); /** * @overload * @param {number} a diff --git a/tests/baselines/reference/overloadTag1.symbols b/tests/baselines/reference/overloadTag1.symbols index 565286ccb6d77..9e53fb21dcec5 100644 --- a/tests/baselines/reference/overloadTag1.symbols +++ b/tests/baselines/reference/overloadTag1.symbols @@ -38,10 +38,16 @@ export function overloaded(a,b) { throw new Error("Invalid arguments"); >Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) } -overloaded(1,2) +var o1 = overloaded(1,2) +>o1 : Symbol(o1, Decl(overloadTag1.js, 23, 3)) >overloaded : Symbol(overloaded, Decl(overloadTag1.js, 0, 0)) -overloaded("zero", "one") +var o2 = overloaded("zero", "one") +>o2 : Symbol(o2, Decl(overloadTag1.js, 24, 3)) +>overloaded : Symbol(overloaded, Decl(overloadTag1.js, 0, 0)) + +var o3 = overloaded("a",false) +>o3 : Symbol(o3, Decl(overloadTag1.js, 25, 3)) >overloaded : Symbol(overloaded, Decl(overloadTag1.js, 0, 0)) /** @@ -56,17 +62,17 @@ overloaded("zero", "one") * @returns {string} */ export function uncheckedInternally(a, b) { ->uncheckedInternally : Symbol(uncheckedInternally, Decl(overloadTag1.js, 24, 25)) ->a : Symbol(a, Decl(overloadTag1.js, 37, 36)) ->b : Symbol(b, Decl(overloadTag1.js, 37, 38)) +>uncheckedInternally : Symbol(uncheckedInternally, Decl(overloadTag1.js, 25, 30)) +>a : Symbol(a, Decl(overloadTag1.js, 38, 36)) +>b : Symbol(b, Decl(overloadTag1.js, 38, 38)) return a + b; ->a : Symbol(a, Decl(overloadTag1.js, 37, 36)) ->b : Symbol(b, Decl(overloadTag1.js, 37, 38)) +>a : Symbol(a, Decl(overloadTag1.js, 38, 36)) +>b : Symbol(b, Decl(overloadTag1.js, 38, 38)) } uncheckedInternally(1,2) ->uncheckedInternally : Symbol(uncheckedInternally, Decl(overloadTag1.js, 24, 25)) +>uncheckedInternally : Symbol(uncheckedInternally, Decl(overloadTag1.js, 25, 30)) uncheckedInternally("zero", "one") ->uncheckedInternally : Symbol(uncheckedInternally, Decl(overloadTag1.js, 24, 25)) +>uncheckedInternally : Symbol(uncheckedInternally, Decl(overloadTag1.js, 25, 30)) diff --git a/tests/baselines/reference/overloadTag1.types b/tests/baselines/reference/overloadTag1.types index a1cc96d9a4657..647eb762b819f 100644 --- a/tests/baselines/reference/overloadTag1.types +++ b/tests/baselines/reference/overloadTag1.types @@ -56,18 +56,27 @@ export function overloaded(a,b) { >Error : ErrorConstructor >"Invalid arguments" : "Invalid arguments" } -overloaded(1,2) +var o1 = overloaded(1,2) +>o1 : number >overloaded(1,2) : number >overloaded : { (a: number, b: number): number; (a: string, b: boolean): string; } >1 : 1 >2 : 2 -overloaded("zero", "one") +var o2 = overloaded("zero", "one") +>o2 : never >overloaded("zero", "one") : never >overloaded : { (a: number, b: number): number; (a: string, b: boolean): string; } >"zero" : "zero" >"one" : "one" +var o3 = overloaded("a",false) +>o3 : string +>overloaded("a",false) : string +>overloaded : { (a: number, b: number): number; (a: string, b: boolean): string; } +>"a" : "a" +>false : false + /** * @overload * @param {number} a diff --git a/tests/cases/conformance/jsdoc/overloadTag1.ts b/tests/cases/conformance/jsdoc/overloadTag1.ts index 0d542a13b5bc2..4eb66b596df44 100644 --- a/tests/cases/conformance/jsdoc/overloadTag1.ts +++ b/tests/cases/conformance/jsdoc/overloadTag1.ts @@ -26,8 +26,9 @@ export function overloaded(a,b) { } throw new Error("Invalid arguments"); } -overloaded(1,2) -overloaded("zero", "one") +var o1 = overloaded(1,2) +var o2 = overloaded("zero", "one") +var o3 = overloaded("a",false) /** * @overload