diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 4b33835bccc..eeb72f42df8 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7234,8 +7234,8 @@ namespace ts { function resolveIntersectionTypeMembers(type: IntersectionType) { // The members and properties collections are empty for intersection types. To get all properties of an // intersection type use getPropertiesOfType (only the language service uses this). - let callSignatures: ReadonlyArray = emptyArray; - let constructSignatures: ReadonlyArray = emptyArray; + let callSignatures: Signature[] | undefined; + let constructSignatures: Signature[] | undefined; let stringIndexInfo: IndexInfo | undefined; let numberIndexInfo: IndexInfo | undefined; const types = type.types; @@ -7257,13 +7257,22 @@ namespace ts { return clone; }); } - constructSignatures = concatenate(constructSignatures, signatures); + constructSignatures = appendSignatures(constructSignatures, signatures); } - callSignatures = concatenate(callSignatures, getSignaturesOfType(t, SignatureKind.Call)); + callSignatures = appendSignatures(callSignatures, getSignaturesOfType(t, SignatureKind.Call)); stringIndexInfo = intersectIndexInfos(stringIndexInfo, getIndexInfoOfType(t, IndexKind.String)); numberIndexInfo = intersectIndexInfos(numberIndexInfo, getIndexInfoOfType(t, IndexKind.Number)); } - setStructuredTypeMembers(type, emptySymbols, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo); + setStructuredTypeMembers(type, emptySymbols, callSignatures || emptyArray, constructSignatures || emptyArray, stringIndexInfo, numberIndexInfo); + } + + function appendSignatures(signatures: Signature[] | undefined, newSignatures: readonly Signature[]) { + for (const sig of newSignatures) { + if (!signatures || every(signatures, s => !compareSignaturesIdentical(s, sig, /*partialMatch*/ false, /*ignoreThisTypes*/ false, /*ignoreReturnTypes*/ false, compareTypesIdentical))) { + signatures = append(signatures, sig); + } + } + return signatures; } /** @@ -14403,20 +14412,25 @@ namespace ts { if (!(isMatchingSignature(source, target, partialMatch))) { return Ternary.False; } - // Check that the two signatures have the same number of type parameters. We might consider - // also checking that any type parameter constraints match, but that would require instantiating - // the constraints with a common set of type arguments to get relatable entities in places where - // type parameters occur in the constraints. The complexity of doing that doesn't seem worthwhile, - // particularly as we're comparing erased versions of the signatures below. + // Check that the two signatures have the same number of type parameters. if (length(source.typeParameters) !== length(target.typeParameters)) { return Ternary.False; } - // Spec 1.0 Section 3.8.3 & 3.8.4: - // M and N (the signatures) are instantiated using type Any as the type argument for all type parameters declared by M and N - source = getErasedSignature(source); - target = getErasedSignature(target); + // Check that type parameter constraints and defaults match. If they do, instantiate the source + // signature with the type parameters of the target signature and continue the comparison. + if (target.typeParameters) { + const mapper = createTypeMapper(source.typeParameters!, target.typeParameters); + for (let i = 0; i < target.typeParameters.length; i++) { + const s = source.typeParameters![i]; + const t = target.typeParameters[i]; + if (!(s === t || compareTypes(instantiateType(getConstraintFromTypeParameter(s), mapper) || unknownType, getConstraintFromTypeParameter(t) || unknownType) && + compareTypes(instantiateType(getDefaultFromTypeParameter(s), mapper) || unknownType, getDefaultFromTypeParameter(t) || unknownType))) { + return Ternary.False; + } + } + source = instantiateSignature(source, mapper, /*eraseTypeParameters*/ true); + } let result = Ternary.True; - if (!ignoreThisTypes) { const sourceThisType = getThisTypeOfSignature(source); if (sourceThisType) { @@ -14430,7 +14444,6 @@ namespace ts { } } } - const targetLen = getParameterCount(target); for (let i = 0; i < targetLen; i++) { const s = getTypeAtPosition(source, i); diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index eb12242a84f..4747b89f08c 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -245,6 +245,7 @@ namespace ts { esnext: ModuleKind.ESNext }), affectsModuleResolution: true, + affectsEmit: true, paramType: Diagnostics.KIND, showInSimplifiedHelpView: true, category: Diagnostics.Basic_Options, @@ -590,6 +591,7 @@ namespace ts { name: "esModuleInterop", type: "boolean", affectsSemanticDiagnostics: true, + affectsEmit: true, showInSimplifiedHelpView: true, category: Diagnostics.Module_Resolution_Options, description: Diagnostics.Enables_emit_interoperability_between_CommonJS_and_ES_Modules_via_creation_of_namespace_objects_for_all_imports_Implies_allowSyntheticDefaultImports diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index b575deab62f..56f11078fc0 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -2201,13 +2201,13 @@ namespace ts { let result: (JSDoc | JSDocTag)[] | undefined; // Pull parameter comments from declaring function as well if (isVariableLike(hostNode) && hasInitializer(hostNode) && hasJSDocNodes(hostNode.initializer!)) { - result = addRange(result, (hostNode.initializer as HasJSDoc).jsDoc!); + result = append(result, last((hostNode.initializer as HasJSDoc).jsDoc!)); } let node: Node | undefined = hostNode; while (node && node.parent) { if (hasJSDocNodes(node)) { - result = addRange(result, node.jsDoc!); + result = append(result, last(node.jsDoc!)); } if (node.kind === SyntaxKind.Parameter) { diff --git a/src/compiler/watch.ts b/src/compiler/watch.ts index d4a97f6f1b8..6963a4df645 100644 --- a/src/compiler/watch.ts +++ b/src/compiler/watch.ts @@ -608,7 +608,6 @@ namespace ts { /*@internal*/ getCurrentProgram(): T; /** Closes the watch */ - /*@internal*/ close(): void; } diff --git a/src/testRunner/unittests/tsbuild/sample.ts b/src/testRunner/unittests/tsbuild/sample.ts index df2fb62db25..420c7a468aa 100644 --- a/src/testRunner/unittests/tsbuild/sample.ts +++ b/src/testRunner/unittests/tsbuild/sample.ts @@ -906,7 +906,7 @@ class someClass { }`), "target": "esnext", } }`); - }, + }, expectedDiagnostics: [ getExpectedDiagnosticForProjectsInBuild("src/core/tsconfig.json"), [Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, "src/core/tsconfig.json", "src/core/anotherModule.js"], @@ -931,6 +931,94 @@ class someClass { }`), baselineOnly: true, verifyDiagnostics: true }); + + verifyTsbuildOutput({ + scenario: "when module option changes", + projFs: () => projFs, + time, + tick, + proj: "sample1", + rootNames: ["/src/core"], + expectedMapFileNames: emptyArray, + lastProjectOutputJs: "/src/core/index.js", + initialBuild: { + modifyFs: fs => fs.writeFileSync("/src/core/tsconfig.json", `{ + "compilerOptions": { + "incremental": true, + "module": "commonjs" + } +}`), + expectedDiagnostics: [ + getExpectedDiagnosticForProjectsInBuild("src/core/tsconfig.json"), + [Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, "src/core/tsconfig.json", "src/core/anotherModule.js"], + [Diagnostics.Building_project_0, "/src/core/tsconfig.json"], + ] + }, + incrementalDtsChangedBuild: { + modifyFs: fs => replaceText(fs, "/src/core/tsconfig.json", `"module": "commonjs"`, `"module": "amd"`), + expectedDiagnostics: [ + getExpectedDiagnosticForProjectsInBuild("src/core/tsconfig.json"), + [Diagnostics.Project_0_is_out_of_date_because_oldest_output_1_is_older_than_newest_input_2, "src/core/tsconfig.json", "src/core/anotherModule.js", "src/core/tsconfig.json"], + [Diagnostics.Building_project_0, "/src/core/tsconfig.json"] + ] + }, + outputFiles: [ + "/src/core/anotherModule.js", + "/src/core/index.js", + "/src/core/tsconfig.tsbuildinfo", + ], + baselineOnly: true, + verifyDiagnostics: true + }); + + verifyTsbuildOutput({ + scenario: "when esModuleInterop option changes", + projFs: () => projFs, + time, + tick, + proj: "sample1", + rootNames: ["/src/tests"], + expectedMapFileNames: emptyArray, + lastProjectOutputJs: "/src/tests/index.js", + initialBuild: { + modifyFs: fs => fs.writeFileSync("/src/tests/tsconfig.json", `{ + "references": [ + { "path": "../core" }, + { "path": "../logic" } + ], + "files": ["index.ts"], + "compilerOptions": { + "composite": true, + "declaration": true, + "forceConsistentCasingInFileNames": true, + "skipDefaultLibCheck": true, + "esModuleInterop": false + } +}`), + expectedDiagnostics: [ + getExpectedDiagnosticForProjectsInBuild("src/core/tsconfig.json", "src/logic/tsconfig.json", "src/tests/tsconfig.json"), + [Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, "src/core/tsconfig.json", "src/core/anotherModule.js"], + [Diagnostics.Building_project_0, "/src/core/tsconfig.json"], + [Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, "src/logic/tsconfig.json", "src/logic/index.js"], + [Diagnostics.Building_project_0, "/src/logic/tsconfig.json"], + [Diagnostics.Project_0_is_out_of_date_because_output_file_1_does_not_exist, "src/tests/tsconfig.json", "src/tests/index.js"], + [Diagnostics.Building_project_0, "/src/tests/tsconfig.json"] + ] + }, + incrementalDtsChangedBuild: { + modifyFs: fs => replaceText(fs, "/src/tests/tsconfig.json", `"esModuleInterop": false`, `"esModuleInterop": true`), + expectedDiagnostics: [ + getExpectedDiagnosticForProjectsInBuild("src/core/tsconfig.json", "src/logic/tsconfig.json", "src/tests/tsconfig.json"), + [Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2, "src/core/tsconfig.json", "src/core/anotherModule.ts", "src/core/anotherModule.js"], + [Diagnostics.Project_0_is_up_to_date_because_newest_input_1_is_older_than_oldest_output_2, "src/logic/tsconfig.json", "src/logic/index.ts", "src/logic/index.js"], + [Diagnostics.Project_0_is_out_of_date_because_oldest_output_1_is_older_than_newest_input_2, "src/tests/tsconfig.json", "src/tests/index.js", "src/tests/tsconfig.json"], + [Diagnostics.Building_project_0, "/src/tests/tsconfig.json"] + ] + }, + outputFiles: [], + baselineOnly: true, + verifyDiagnostics: true + }); }); }); } diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 94e023ec9b6..e9d797bfa0d 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -4553,6 +4553,8 @@ declare namespace ts { interface Watch { /** Synchronize with host and get updated program */ getProgram(): T; + /** Closes the watch */ + close(): void; } /** * Creates the watch what generates program using the config file diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 9ce1498fd3b..be8eea8062b 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -4553,6 +4553,8 @@ declare namespace ts { interface Watch { /** Synchronize with host and get updated program */ getProgram(): T; + /** Closes the watch */ + close(): void; } /** * Creates the watch what generates program using the config file diff --git a/tests/baselines/reference/genericSignatureIdentity.errors.txt b/tests/baselines/reference/genericSignatureIdentity.errors.txt new file mode 100644 index 00000000000..6aed55a1237 --- /dev/null +++ b/tests/baselines/reference/genericSignatureIdentity.errors.txt @@ -0,0 +1,36 @@ +tests/cases/compiler/genericSignatureIdentity.ts(10,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type '(x: T) => T', but here has type '(x: T) => T'. +tests/cases/compiler/genericSignatureIdentity.ts(14,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type '(x: T) => T', but here has type '(x: T) => T'. +tests/cases/compiler/genericSignatureIdentity.ts(18,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type '(x: T) => T', but here has type '(x: any) => any'. + + +==== tests/cases/compiler/genericSignatureIdentity.ts (3 errors) ==== + // This test is here to remind us of our current limits of type identity checking. + // Ideally all of the below declarations would be considered different (and thus errors) + // but they aren't because we erase type parameters to type any and don't check that + // constraints are identical. + + var x: { + (x: T): T; + }; + + var x: { + ~ +!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type '(x: T) => T', but here has type '(x: T) => T'. +!!! related TS6203 tests/cases/compiler/genericSignatureIdentity.ts:6:5: 'x' was also declared here. + (x: T): T; + }; + + var x: { + ~ +!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type '(x: T) => T', but here has type '(x: T) => T'. +!!! related TS6203 tests/cases/compiler/genericSignatureIdentity.ts:6:5: 'x' was also declared here. + (x: T): T; + }; + + var x: { + ~ +!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type '(x: T) => T', but here has type '(x: any) => any'. +!!! related TS6203 tests/cases/compiler/genericSignatureIdentity.ts:6:5: 'x' was also declared here. + (x: any): any; + }; + \ No newline at end of file diff --git a/tests/baselines/reference/identityForSignaturesWithTypeParametersAndAny.errors.txt b/tests/baselines/reference/identityForSignaturesWithTypeParametersAndAny.errors.txt index 092bfaaeeb3..11fb2950aa8 100644 --- a/tests/baselines/reference/identityForSignaturesWithTypeParametersAndAny.errors.txt +++ b/tests/baselines/reference/identityForSignaturesWithTypeParametersAndAny.errors.txt @@ -1,12 +1,16 @@ +tests/cases/compiler/identityForSignaturesWithTypeParametersAndAny.ts(2,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'f' must be of type '(x: T, y: U) => T', but here has type '(x: any, y: any) => any'. tests/cases/compiler/identityForSignaturesWithTypeParametersAndAny.ts(5,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'g' must be of type '(x: T, y: U) => T', but here has type '(x: any, y: any) => any'. tests/cases/compiler/identityForSignaturesWithTypeParametersAndAny.ts(8,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'h' must be of type '(x: T, y: U) => T', but here has type '(x: any, y: any) => any'. tests/cases/compiler/identityForSignaturesWithTypeParametersAndAny.ts(11,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'i' must be of type '(x: T, y: U) => T', but here has type '(x: any, y: string) => any'. tests/cases/compiler/identityForSignaturesWithTypeParametersAndAny.ts(14,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'j' must be of type '(x: T, y: U) => T', but here has type '(x: any, y: any) => string'. -==== tests/cases/compiler/identityForSignaturesWithTypeParametersAndAny.ts (4 errors) ==== +==== tests/cases/compiler/identityForSignaturesWithTypeParametersAndAny.ts (5 errors) ==== var f: (x: T, y: U) => T; var f: (x: any, y: any) => any; + ~ +!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'f' must be of type '(x: T, y: U) => T', but here has type '(x: any, y: any) => any'. +!!! related TS6203 tests/cases/compiler/identityForSignaturesWithTypeParametersAndAny.ts:1:5: 'f' was also declared here. var g: (x: T, y: U) => T; var g: (x: any, y: any) => any; diff --git a/tests/baselines/reference/identityForSignaturesWithTypeParametersSwitched.errors.txt b/tests/baselines/reference/identityForSignaturesWithTypeParametersSwitched.errors.txt new file mode 100644 index 00000000000..81d0eb6c961 --- /dev/null +++ b/tests/baselines/reference/identityForSignaturesWithTypeParametersSwitched.errors.txt @@ -0,0 +1,9 @@ +tests/cases/compiler/identityForSignaturesWithTypeParametersSwitched.ts(2,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'f' must be of type '(x: T, y: U) => T', but here has type '(x: U, y: T) => U'. + + +==== tests/cases/compiler/identityForSignaturesWithTypeParametersSwitched.ts (1 errors) ==== + var f: (x: T, y: U) => T; + var f: (x: U, y: T) => U; + ~ +!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'f' must be of type '(x: T, y: U) => T', but here has type '(x: U, y: T) => U'. +!!! related TS6203 tests/cases/compiler/identityForSignaturesWithTypeParametersSwitched.ts:1:5: 'f' was also declared here. \ No newline at end of file diff --git a/tests/baselines/reference/keyofAndIndexedAccess2.errors.txt b/tests/baselines/reference/keyofAndIndexedAccess2.errors.txt index ff96efe3e13..b00409544de 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess2.errors.txt +++ b/tests/baselines/reference/keyofAndIndexedAccess2.errors.txt @@ -237,4 +237,13 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts(108,5): error TS23 type Baz> = { [K in keyof Q]: T[Q[K]] }; type Qux> = { [K in keyof Q]: T[Q[K]["0"]] }; + + // Repro from #32038 + + const actions = ['resizeTo', 'resizeBy'] as const; + for (const action of actions) { + window[action] = (x, y) => { + window[action](x, y); + } + } \ No newline at end of file diff --git a/tests/baselines/reference/keyofAndIndexedAccess2.js b/tests/baselines/reference/keyofAndIndexedAccess2.js index 91cf2c89ff2..a2d7f9b2fdd 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess2.js +++ b/tests/baselines/reference/keyofAndIndexedAccess2.js @@ -156,6 +156,15 @@ type Bar = { [key: string]: { [K in keyof T]: [K] }[keyof T] }; type Baz> = { [K in keyof Q]: T[Q[K]] }; type Qux> = { [K in keyof Q]: T[Q[K]["0"]] }; + +// Repro from #32038 + +const actions = ['resizeTo', 'resizeBy'] as const; +for (const action of actions) { + window[action] = (x, y) => { + window[action](x, y); + } +} //// [keyofAndIndexedAccess2.js] @@ -253,3 +262,10 @@ export class c { this["a"] = "b"; } } +// Repro from #32038 +const actions = ['resizeTo', 'resizeBy']; +for (const action of actions) { + window[action] = (x, y) => { + window[action](x, y); + }; +} diff --git a/tests/baselines/reference/keyofAndIndexedAccess2.symbols b/tests/baselines/reference/keyofAndIndexedAccess2.symbols index 4a7721ff801..58b5f470c03 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess2.symbols +++ b/tests/baselines/reference/keyofAndIndexedAccess2.symbols @@ -564,3 +564,26 @@ type Qux> = { [K in keyof Q]: T[Q[K]["0"]] }; >Q : Symbol(Q, Decl(keyofAndIndexedAccess2.ts, 156, 11)) >K : Symbol(K, Decl(keyofAndIndexedAccess2.ts, 156, 35)) +// Repro from #32038 + +const actions = ['resizeTo', 'resizeBy'] as const; +>actions : Symbol(actions, Decl(keyofAndIndexedAccess2.ts, 160, 5)) + +for (const action of actions) { +>action : Symbol(action, Decl(keyofAndIndexedAccess2.ts, 161, 10)) +>actions : Symbol(actions, Decl(keyofAndIndexedAccess2.ts, 160, 5)) + + window[action] = (x, y) => { +>window : Symbol(window, Decl(lib.dom.d.ts, --, --)) +>action : Symbol(action, Decl(keyofAndIndexedAccess2.ts, 161, 10)) +>x : Symbol(x, Decl(keyofAndIndexedAccess2.ts, 162, 19)) +>y : Symbol(y, Decl(keyofAndIndexedAccess2.ts, 162, 21)) + + window[action](x, y); +>window : Symbol(window, Decl(lib.dom.d.ts, --, --)) +>action : Symbol(action, Decl(keyofAndIndexedAccess2.ts, 161, 10)) +>x : Symbol(x, Decl(keyofAndIndexedAccess2.ts, 162, 19)) +>y : Symbol(y, Decl(keyofAndIndexedAccess2.ts, 162, 21)) + } +} + diff --git a/tests/baselines/reference/keyofAndIndexedAccess2.types b/tests/baselines/reference/keyofAndIndexedAccess2.types index b282588cc51..5824619c6ee 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess2.types +++ b/tests/baselines/reference/keyofAndIndexedAccess2.types @@ -540,3 +540,35 @@ type Baz> = { [K in keyof Q]: T[Q[K]] }; type Qux> = { [K in keyof Q]: T[Q[K]["0"]] }; >Qux : Qux +// Repro from #32038 + +const actions = ['resizeTo', 'resizeBy'] as const; +>actions : readonly ["resizeTo", "resizeBy"] +>['resizeTo', 'resizeBy'] as const : readonly ["resizeTo", "resizeBy"] +>['resizeTo', 'resizeBy'] : readonly ["resizeTo", "resizeBy"] +>'resizeTo' : "resizeTo" +>'resizeBy' : "resizeBy" + +for (const action of actions) { +>action : "resizeTo" | "resizeBy" +>actions : readonly ["resizeTo", "resizeBy"] + + window[action] = (x, y) => { +>window[action] = (x, y) => { window[action](x, y); } : (x: number, y: number) => void +>window[action] : ((x: number, y: number) => void) & ((x: number, y: number) => void) +>window : Window +>action : "resizeTo" | "resizeBy" +>(x, y) => { window[action](x, y); } : (x: number, y: number) => void +>x : number +>y : number + + window[action](x, y); +>window[action](x, y) : void +>window[action] : ((x: number, y: number) => void) | ((x: number, y: number) => void) +>window : Window +>action : "resizeTo" | "resizeBy" +>x : number +>y : number + } +} + diff --git a/tests/baselines/reference/promiseIdentity.errors.txt b/tests/baselines/reference/promiseIdentity.errors.txt new file mode 100644 index 00000000000..b104dc68e5f --- /dev/null +++ b/tests/baselines/reference/promiseIdentity.errors.txt @@ -0,0 +1,28 @@ +tests/cases/compiler/promiseIdentity.ts(21,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'y' must be of type 'IPromise2', but here has type 'Promise2'. + + +==== tests/cases/compiler/promiseIdentity.ts (1 errors) ==== + export interface IPromise { + then(callback: (x: T) => IPromise): IPromise; + } + interface Promise { + then(callback: (x: T) => Promise): Promise; + } + var x: IPromise; + var x: Promise; + + + interface IPromise2 { + then(callback: (x: T) => IPromise2): IPromise2; + } + interface Promise2 { + then(callback: (x: V) => Promise2): Promise2; // Uses V instead of T in callback's parameter + } + + // Ok because T in this particular Promise2 is any, as are all the U and W references. + // Also, the V of Promise2 happens to coincide with the T of IPromise2 (they are both string). + var y: IPromise2; + var y: Promise2; + ~ +!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'y' must be of type 'IPromise2', but here has type 'Promise2'. +!!! related TS6203 tests/cases/compiler/promiseIdentity.ts:20:5: 'y' was also declared here. \ No newline at end of file diff --git a/tests/baselines/reference/promiseIdentityWithAny.errors.txt b/tests/baselines/reference/promiseIdentityWithAny.errors.txt new file mode 100644 index 00000000000..c318925c617 --- /dev/null +++ b/tests/baselines/reference/promiseIdentityWithAny.errors.txt @@ -0,0 +1,17 @@ +tests/cases/compiler/promiseIdentityWithAny.ts(10,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type 'IPromise', but here has type 'Promise'. + + +==== tests/cases/compiler/promiseIdentityWithAny.ts (1 errors) ==== + export interface IPromise { + then(callback: (x: T) => IPromise): IPromise; + } + export interface Promise { + then(callback: (x: T) => Promise): Promise; + } + + // Should be ok because signature type parameters get erased to any + var x: IPromise; + var x: Promise; + ~ +!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type 'IPromise', but here has type 'Promise'. +!!! related TS6203 tests/cases/compiler/promiseIdentityWithAny.ts:9:5: 'x' was also declared here. \ No newline at end of file diff --git a/tests/baselines/reference/promiseIdentityWithConstraints.errors.txt b/tests/baselines/reference/promiseIdentityWithConstraints.errors.txt new file mode 100644 index 00000000000..9b72f8363ed --- /dev/null +++ b/tests/baselines/reference/promiseIdentityWithConstraints.errors.txt @@ -0,0 +1,17 @@ +tests/cases/compiler/promiseIdentityWithConstraints.ts(10,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type 'IPromise', but here has type 'Promise'. + + +==== tests/cases/compiler/promiseIdentityWithConstraints.ts (1 errors) ==== + export interface IPromise { + then(callback: (x: T) => IPromise): IPromise; + } + export interface Promise { + then(callback: (x: T) => Promise): Promise; + } + + // Error because constraint V doesn't match + var x: IPromise; + var x: Promise; + ~ +!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'x' must be of type 'IPromise', but here has type 'Promise'. +!!! related TS6203 tests/cases/compiler/promiseIdentityWithConstraints.ts:9:5: 'x' was also declared here. \ No newline at end of file diff --git a/tests/baselines/reference/syntaxErrors.symbols b/tests/baselines/reference/syntaxErrors.symbols index 2062b13c0b9..e28b5de936f 100644 --- a/tests/baselines/reference/syntaxErrors.symbols +++ b/tests/baselines/reference/syntaxErrors.symbols @@ -17,12 +17,8 @@ function f(x, y, skipped) { >skipped : Symbol(skipped, Decl(badTypeArguments.js, 4, 16)) return x.t + y.t; ->x.t : Symbol(C.t, Decl(dummyType.d.ts, 0, 20)) >x : Symbol(x, Decl(badTypeArguments.js, 4, 11)) ->t : Symbol(C.t, Decl(dummyType.d.ts, 0, 20)) ->y.t : Symbol(C.t, Decl(dummyType.d.ts, 0, 20)) >y : Symbol(y, Decl(badTypeArguments.js, 4, 13)) ->t : Symbol(C.t, Decl(dummyType.d.ts, 0, 20)) } var x = f({ t: 1000 }, { t: 3000 }, { t: 5000 }); >x : Symbol(x, Decl(badTypeArguments.js, 7, 3)) diff --git a/tests/baselines/reference/syntaxErrors.types b/tests/baselines/reference/syntaxErrors.types index c9af0176008..874a6857515 100644 --- a/tests/baselines/reference/syntaxErrors.types +++ b/tests/baselines/reference/syntaxErrors.types @@ -9,24 +9,24 @@ declare class C { t: T } // @ts-ignore /** @param {C.} skipped */ function f(x, y, skipped) { ->f : (x: C, y: C, skipped: C) => any ->x : C ->y : C +>f : (x: any, y: any, skipped: C) => any +>x : any +>y : any >skipped : C return x.t + y.t; >x.t + y.t : any >x.t : any ->x : C +>x : any +>t : any +>y.t : any +>y : any >t : any ->y.t : number ->y : C ->t : number } var x = f({ t: 1000 }, { t: 3000 }, { t: 5000 }); >x : any >f({ t: 1000 }, { t: 3000 }, { t: 5000 }) : any ->f : (x: C, y: C, skipped: C) => any +>f : (x: any, y: any, skipped: C) => any >{ t: 1000 } : { t: number; } >t : number >1000 : 1000 diff --git a/tests/baselines/reference/tsbuild/sample1/incremental-declaration-changes/when-esModuleInterop-option-changes.js b/tests/baselines/reference/tsbuild/sample1/incremental-declaration-changes/when-esModuleInterop-option-changes.js new file mode 100644 index 00000000000..28c559ee72a --- /dev/null +++ b/tests/baselines/reference/tsbuild/sample1/incremental-declaration-changes/when-esModuleInterop-option-changes.js @@ -0,0 +1,96 @@ +//// [/src/tests/index.js] +"use strict"; +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result["default"] = mod; + return result; +}; +exports.__esModule = true; +var c = __importStar(require("../core/index")); +var logic = __importStar(require("../logic/index")); +c.leftPad("", 10); +logic.getSecondsInDay(); +var mod = __importStar(require("../core/anotherModule")); +exports.m = mod; + + +//// [/src/tests/tsconfig.json] +{ + "references": [ + { "path": "../core" }, + { "path": "../logic" } + ], + "files": ["index.ts"], + "compilerOptions": { + "composite": true, + "declaration": true, + "forceConsistentCasingInFileNames": true, + "skipDefaultLibCheck": true, + "esModuleInterop": true + } +} + +//// [/src/tests/tsconfig.tsbuildinfo] +{ + "program": { + "fileInfos": { + "../../lib/lib.d.ts": { + "version": "-15964756381", + "signature": "-15964756381" + }, + "../core/index.ts": { + "version": "-13851440507", + "signature": "-13851440507" + }, + "../core/anothermodule.ts": { + "version": "7652028357", + "signature": "7652028357" + }, + "../logic/index.ts": { + "version": "-6548680073", + "signature": "-6548680073" + }, + "./index.ts": { + "version": "12336236525", + "signature": "-9209611" + } + }, + "options": { + "composite": true, + "declaration": true, + "forceConsistentCasingInFileNames": true, + "skipDefaultLibCheck": true, + "esModuleInterop": true, + "configFilePath": "./tsconfig.json" + }, + "referencedMap": { + "../logic/index.ts": [ + "../core/anothermodule.d.ts" + ], + "./index.ts": [ + "../core/anothermodule.d.ts", + "../core/index.d.ts", + "../logic/index.d.ts" + ] + }, + "exportedModulesMap": { + "../logic/index.ts": [ + "../core/anothermodule.d.ts" + ], + "./index.ts": [ + "../core/anothermodule.d.ts" + ] + }, + "semanticDiagnosticsPerFile": [ + "../../lib/lib.d.ts", + "../core/anothermodule.ts", + "../core/index.ts", + "../logic/index.ts", + "./index.ts" + ] + }, + "version": "FakeTSVersion" +} + diff --git a/tests/baselines/reference/tsbuild/sample1/incremental-declaration-changes/when-module-option-changes.js b/tests/baselines/reference/tsbuild/sample1/incremental-declaration-changes/when-module-option-changes.js new file mode 100644 index 00000000000..a73ad73c155 --- /dev/null +++ b/tests/baselines/reference/tsbuild/sample1/incremental-declaration-changes/when-module-option-changes.js @@ -0,0 +1,66 @@ +//// [/src/core/anotherModule.js] +define(["require", "exports"], function (require, exports) { + "use strict"; + exports.__esModule = true; + exports.World = "hello"; +}); + + +//// [/src/core/index.js] +define(["require", "exports"], function (require, exports) { + "use strict"; + exports.__esModule = true; + exports.someString = "HELLO WORLD"; + function leftPad(s, n) { return s + n; } + exports.leftPad = leftPad; + function multiply(a, b) { return a * b; } + exports.multiply = multiply; +}); + + +//// [/src/core/tsconfig.json] +{ + "compilerOptions": { + "incremental": true, + "module": "amd" + } +} + +//// [/src/core/tsconfig.tsbuildinfo] +{ + "program": { + "fileInfos": { + "../../lib/lib.d.ts": { + "version": "-15964756381", + "signature": "-15964756381" + }, + "./anothermodule.ts": { + "version": "-2676574883", + "signature": "-8396256275" + }, + "./index.ts": { + "version": "-18749805970", + "signature": "1874987148" + }, + "./some_decl.d.ts": { + "version": "-9253692965", + "signature": "-9253692965" + } + }, + "options": { + "incremental": true, + "module": 2, + "configFilePath": "./tsconfig.json" + }, + "referencedMap": {}, + "exportedModulesMap": {}, + "semanticDiagnosticsPerFile": [ + "../../lib/lib.d.ts", + "./anothermodule.ts", + "./index.ts", + "./some_decl.d.ts" + ] + }, + "version": "FakeTSVersion" +} + diff --git a/tests/baselines/reference/tsbuild/sample1/initial-Build/when-esModuleInterop-option-changes.js b/tests/baselines/reference/tsbuild/sample1/initial-Build/when-esModuleInterop-option-changes.js new file mode 100644 index 00000000000..b6f0b53b89c --- /dev/null +++ b/tests/baselines/reference/tsbuild/sample1/initial-Build/when-esModuleInterop-option-changes.js @@ -0,0 +1,237 @@ +//// [/src/core/anotherModule.d.ts] +export declare const World = "hello"; +//# sourceMappingURL=anotherModule.d.ts.map + +//// [/src/core/anotherModule.d.ts.map] +{"version":3,"file":"anotherModule.d.ts","sourceRoot":"","sources":["anotherModule.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,KAAK,UAAU,CAAC"} + +//// [/src/core/anotherModule.js] +"use strict"; +exports.__esModule = true; +exports.World = "hello"; + + +//// [/src/core/index.d.ts] +export declare const someString: string; +export declare function leftPad(s: string, n: number): string; +export declare function multiply(a: number, b: number): number; +//# sourceMappingURL=index.d.ts.map + +//// [/src/core/index.d.ts.map] +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,UAAU,EAAE,MAAsB,CAAC;AAChD,wBAAgB,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,UAAmB;AAC/D,wBAAgB,QAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,UAAmB"} + +//// [/src/core/index.js] +"use strict"; +exports.__esModule = true; +exports.someString = "HELLO WORLD"; +function leftPad(s, n) { return s + n; } +exports.leftPad = leftPad; +function multiply(a, b) { return a * b; } +exports.multiply = multiply; + + +//// [/src/core/tsconfig.tsbuildinfo] +{ + "program": { + "fileInfos": { + "../../lib/lib.d.ts": { + "version": "-15964756381", + "signature": "-15964756381" + }, + "./anothermodule.ts": { + "version": "-2676574883", + "signature": "25219880154" + }, + "./index.ts": { + "version": "-18749805970", + "signature": "11051732871" + }, + "./some_decl.d.ts": { + "version": "-9253692965", + "signature": "-9253692965" + } + }, + "options": { + "composite": true, + "declaration": true, + "declarationMap": true, + "skipDefaultLibCheck": true, + "configFilePath": "./tsconfig.json" + }, + "referencedMap": {}, + "exportedModulesMap": {}, + "semanticDiagnosticsPerFile": [ + "../../lib/lib.d.ts", + "./anothermodule.ts", + "./index.ts", + "./some_decl.d.ts" + ] + }, + "version": "FakeTSVersion" +} + +//// [/src/logic/index.d.ts] +export declare function getSecondsInDay(): number; +import * as mod from '../core/anotherModule'; +export declare const m: typeof mod; + + +//// [/src/logic/index.js] +"use strict"; +exports.__esModule = true; +var c = require("../core/index"); +function getSecondsInDay() { + return c.multiply(10, 15); +} +exports.getSecondsInDay = getSecondsInDay; +var mod = require("../core/anotherModule"); +exports.m = mod; +//# sourceMappingURL=index.js.map + +//// [/src/logic/index.js.map] +{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":";;AAAA,iCAAmC;AACnC,SAAgB,eAAe;IAC3B,OAAO,CAAC,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;AAC9B,CAAC;AAFD,0CAEC;AACD,2CAA6C;AAChC,QAAA,CAAC,GAAG,GAAG,CAAC"} + +//// [/src/logic/tsconfig.tsbuildinfo] +{ + "program": { + "fileInfos": { + "../../lib/lib.d.ts": { + "version": "-15964756381", + "signature": "-15964756381" + }, + "../core/index.ts": { + "version": "-13851440507", + "signature": "-13851440507" + }, + "../core/anothermodule.ts": { + "version": "7652028357", + "signature": "7652028357" + }, + "./index.ts": { + "version": "-5786964698", + "signature": "-6548680073" + } + }, + "options": { + "composite": true, + "declaration": true, + "sourceMap": true, + "forceConsistentCasingInFileNames": true, + "skipDefaultLibCheck": true, + "configFilePath": "./tsconfig.json" + }, + "referencedMap": { + "./index.ts": [ + "../core/anothermodule.d.ts", + "../core/index.d.ts" + ] + }, + "exportedModulesMap": { + "./index.ts": [ + "../core/anothermodule.d.ts" + ] + }, + "semanticDiagnosticsPerFile": [ + "../../lib/lib.d.ts", + "../core/anothermodule.ts", + "../core/index.ts", + "./index.ts" + ] + }, + "version": "FakeTSVersion" +} + +//// [/src/tests/index.d.ts] +import * as mod from '../core/anotherModule'; +export declare const m: typeof mod; + + +//// [/src/tests/index.js] +"use strict"; +exports.__esModule = true; +var c = require("../core/index"); +var logic = require("../logic/index"); +c.leftPad("", 10); +logic.getSecondsInDay(); +var mod = require("../core/anotherModule"); +exports.m = mod; + + +//// [/src/tests/tsconfig.json] +{ + "references": [ + { "path": "../core" }, + { "path": "../logic" } + ], + "files": ["index.ts"], + "compilerOptions": { + "composite": true, + "declaration": true, + "forceConsistentCasingInFileNames": true, + "skipDefaultLibCheck": true, + "esModuleInterop": false + } +} + +//// [/src/tests/tsconfig.tsbuildinfo] +{ + "program": { + "fileInfos": { + "../../lib/lib.d.ts": { + "version": "-15964756381", + "signature": "-15964756381" + }, + "../core/index.ts": { + "version": "-13851440507", + "signature": "-13851440507" + }, + "../core/anothermodule.ts": { + "version": "7652028357", + "signature": "7652028357" + }, + "../logic/index.ts": { + "version": "-6548680073", + "signature": "-6548680073" + }, + "./index.ts": { + "version": "12336236525", + "signature": "-9209611" + } + }, + "options": { + "composite": true, + "declaration": true, + "forceConsistentCasingInFileNames": true, + "skipDefaultLibCheck": true, + "esModuleInterop": false, + "configFilePath": "./tsconfig.json" + }, + "referencedMap": { + "../logic/index.ts": [ + "../core/anothermodule.d.ts" + ], + "./index.ts": [ + "../core/anothermodule.d.ts", + "../core/index.d.ts", + "../logic/index.d.ts" + ] + }, + "exportedModulesMap": { + "../logic/index.ts": [ + "../core/anothermodule.d.ts" + ], + "./index.ts": [ + "../core/anothermodule.d.ts" + ] + }, + "semanticDiagnosticsPerFile": [ + "../../lib/lib.d.ts", + "../core/anothermodule.ts", + "../core/index.ts", + "../logic/index.ts", + "./index.ts" + ] + }, + "version": "FakeTSVersion" +} + diff --git a/tests/baselines/reference/tsbuild/sample1/initial-Build/when-module-option-changes.js b/tests/baselines/reference/tsbuild/sample1/initial-Build/when-module-option-changes.js new file mode 100644 index 00000000000..54e0f764dac --- /dev/null +++ b/tests/baselines/reference/tsbuild/sample1/initial-Build/when-module-option-changes.js @@ -0,0 +1,62 @@ +//// [/src/core/anotherModule.js] +"use strict"; +exports.__esModule = true; +exports.World = "hello"; + + +//// [/src/core/index.js] +"use strict"; +exports.__esModule = true; +exports.someString = "HELLO WORLD"; +function leftPad(s, n) { return s + n; } +exports.leftPad = leftPad; +function multiply(a, b) { return a * b; } +exports.multiply = multiply; + + +//// [/src/core/tsconfig.json] +{ + "compilerOptions": { + "incremental": true, + "module": "commonjs" + } +} + +//// [/src/core/tsconfig.tsbuildinfo] +{ + "program": { + "fileInfos": { + "../../lib/lib.d.ts": { + "version": "-15964756381", + "signature": "-15964756381" + }, + "./anothermodule.ts": { + "version": "-2676574883", + "signature": "-8396256275" + }, + "./index.ts": { + "version": "-18749805970", + "signature": "1874987148" + }, + "./some_decl.d.ts": { + "version": "-9253692965", + "signature": "-9253692965" + } + }, + "options": { + "incremental": true, + "module": 1, + "configFilePath": "./tsconfig.json" + }, + "referencedMap": {}, + "exportedModulesMap": {}, + "semanticDiagnosticsPerFile": [ + "../../lib/lib.d.ts", + "./anothermodule.ts", + "./index.ts", + "./some_decl.d.ts" + ] + }, + "version": "FakeTSVersion" +} + diff --git a/tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts b/tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts index b242aa3de60..a86f4718e35 100644 --- a/tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts +++ b/tests/cases/conformance/types/keyof/keyofAndIndexedAccess2.ts @@ -158,3 +158,12 @@ type Bar = { [key: string]: { [K in keyof T]: [K] }[keyof T] }; type Baz> = { [K in keyof Q]: T[Q[K]] }; type Qux> = { [K in keyof Q]: T[Q[K]["0"]] }; + +// Repro from #32038 + +const actions = ['resizeTo', 'resizeBy'] as const; +for (const action of actions) { + window[action] = (x, y) => { + window[action](x, y); + } +} diff --git a/tests/cases/fourslash/commentsCommentParsing.ts b/tests/cases/fourslash/commentsCommentParsing.ts index fe3d44d3e6a..4731194ba69 100644 --- a/tests/cases/fourslash/commentsCommentParsing.ts +++ b/tests/cases/fourslash/commentsCommentParsing.ts @@ -26,7 +26,7 @@ ////} ////jsDocM/*4q*/ultiLine(/*4*/); //// -/////** this is multiple line jsdoc stule comment +/////** multiple line jsdoc comments no longer merge ////*New line1 ////*New Line2*/ /////** Shoul mege this line as well @@ -99,13 +99,13 @@ //// return /*18*/a + b; ////} /////*15*/s/*16q*/um(/*16*/10, /*17*/20); -/////** This is multiplication function*/ -/////** @param */ -/////** @param a first number*/ -/////** @param b */ -/////** @param c { -//// @param d @anotherTag*/ -/////** @param e LastParam @anotherTag*/ +/////** This is multiplication function +//// * @param +//// * @param a first number +//// * @param b +//// * @param c { +//// @param d @anotherTag +//// * @param e LastParam @anotherTag*/ ////function multiply(/*19aq*/a: number, /*20aq*/b: number, /*21aq*/c?: number, /*22aq*/d?, /*23aq*/e?) { ////} ////mult/*19q*/iply(/*19*/10,/*20*/ 20,/*21*/ 30, /*22*/40, /*23*/50); @@ -214,26 +214,26 @@ verify.quickInfoAt("3q", "function jsDocSingleLine(): void", "this is eg of sing verify.signatureHelp({ marker: "4", docComment: "this is multiple line jsdoc stule comment\nNew line1\nNew Line2" }); verify.quickInfoAt("4q", "function jsDocMultiLine(): void", "this is multiple line jsdoc stule comment\nNew line1\nNew Line2"); -verify.signatureHelp({ marker: "5", docComment: "this is multiple line jsdoc stule comment\nNew line1\nNew Line2\nShoul mege this line as well\nand this too\nAnother this one too" }); -verify.quickInfoAt("5q", "function jsDocMultiLineMerge(): void", "this is multiple line jsdoc stule comment\nNew line1\nNew Line2\nShoul mege this line as well\nand this too\nAnother this one too"); +verify.signatureHelp({ marker: "5", docComment: "Another this one too" }); +verify.quickInfoAt("5q", "function jsDocMultiLineMerge(): void", "Another this one too"); verify.signatureHelp({ marker: "6", docComment: "jsdoc comment" }); verify.quickInfoAt("6q", "function jsDocMixedComments1(): void", "jsdoc comment"); -verify.signatureHelp({ marker: "7", docComment: "jsdoc comment\nanother jsDocComment" }); -verify.quickInfoAt("7q", "function jsDocMixedComments2(): void", "jsdoc comment\nanother jsDocComment"); +verify.signatureHelp({ marker: "7", docComment: "another jsDocComment" }); +verify.quickInfoAt("7q", "function jsDocMixedComments2(): void", "another jsDocComment"); -verify.signatureHelp({ marker: "8", docComment: "jsdoc comment\n* triplestar jsDocComment" }); -verify.quickInfoAt("8q", "function jsDocMixedComments3(): void", "jsdoc comment\n* triplestar jsDocComment"); +verify.signatureHelp({ marker: "8", docComment: "* triplestar jsDocComment" }); +verify.quickInfoAt("8q", "function jsDocMixedComments3(): void", "* triplestar jsDocComment"); -verify.signatureHelp({ marker: "9", docComment: "jsdoc comment\nanother jsDocComment" }); -verify.quickInfoAt("9q", "function jsDocMixedComments4(): void", "jsdoc comment\nanother jsDocComment"); +verify.signatureHelp({ marker: "9", docComment: "another jsDocComment" }); +verify.quickInfoAt("9q", "function jsDocMixedComments4(): void", "another jsDocComment"); -verify.signatureHelp({ marker: "10", docComment: "jsdoc comment\nanother jsDocComment" }); -verify.quickInfoAt("10q", "function jsDocMixedComments5(): void", "jsdoc comment\nanother jsDocComment"); +verify.signatureHelp({ marker: "10", docComment: "another jsDocComment" }); +verify.quickInfoAt("10q", "function jsDocMixedComments5(): void", "another jsDocComment"); -verify.signatureHelp({ marker: "11", docComment: "another jsDocComment\njsdoc comment" }); -verify.quickInfoAt("11q", "function jsDocMixedComments6(): void", "another jsDocComment\njsdoc comment"); +verify.signatureHelp({ marker: "11", docComment: "jsdoc comment" }); +verify.quickInfoAt("11q", "function jsDocMixedComments6(): void", "jsdoc comment"); verify.signatureHelp({ marker: "12", docComment: "" }); verify.quickInfoAt("12q", "function noHelpComment1(): void"); diff --git a/tests/cases/fourslash/server/jsdocCallbackTag.ts b/tests/cases/fourslash/server/jsdocCallbackTag.ts index 700419cd682..1d754c08608 100644 --- a/tests/cases/fourslash/server/jsdocCallbackTag.ts +++ b/tests/cases/fourslash/server/jsdocCallbackTag.ts @@ -37,18 +37,15 @@ verify.signatureHelp({ marker: '4', text: "t(eventName: string, eventName2: string | number, eventName3: any): number", parameterDocComment: "- So many words", - tags: [{ name: "callback", text: "FooHandler - A kind of magic" }, - { name: "type", text: "{FooHandler} callback" }] + tags: [{ name: "type", text: "{FooHandler} callback" }] }); verify.signatureHelp({ marker: '5', parameterDocComment: "- Silence is golden", - tags: [{ name: "callback", text: "FooHandler - A kind of magic" }, - { name: "type", text: "{FooHandler} callback" }] + tags: [{ name: "type", text: "{FooHandler} callback" }] }); verify.signatureHelp({ marker: '6', parameterDocComment: "- Osterreich mos def", - tags: [{ name: "callback", text: "FooHandler - A kind of magic" }, - { name: "type", text: "{FooHandler} callback" }] + tags: [{ name: "type", text: "{FooHandler} callback" }] });