From 75ac6eb28442de54c646720890205d31e312e416 Mon Sep 17 00:00:00 2001 From: Collins Abitekaniza Date: Mon, 19 Aug 2019 03:10:08 +0300 Subject: [PATCH 01/10] restrict object spreading on unkown type --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 1dc46fe9568..53f96d507b8 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -19878,7 +19878,7 @@ namespace ts { return isValidSpreadType(constraint); } } - return !!(type.flags & (TypeFlags.AnyOrUnknown | TypeFlags.NonPrimitive | TypeFlags.Object | TypeFlags.InstantiableNonPrimitive) || + return !!(type.flags & (TypeFlags.Any | TypeFlags.NonPrimitive | TypeFlags.Object | TypeFlags.InstantiableNonPrimitive) || getFalsyFlags(type) & TypeFlags.DefinitelyFalsy && isValidSpreadType(removeDefinitelyFalsyTypes(type)) || type.flags & TypeFlags.UnionOrIntersection && every((type).types, isValidSpreadType)); } From 0341c2fe757213e4af04dcfe1a6926559218b08f Mon Sep 17 00:00:00 2001 From: Collins Abitekaniza Date: Mon, 19 Aug 2019 03:23:33 +0300 Subject: [PATCH 02/10] add baseline for unknown type spread --- .../reference/unknownType1.errors.txt | 19 ++++-- tests/baselines/reference/unknownType1.js | 2 + .../baselines/reference/unknownType1.symbols | 67 ++++++++++--------- tests/baselines/reference/unknownType1.types | 11 ++- .../conformance/types/unknown/unknownType1.ts | 1 + 5 files changed, 61 insertions(+), 39 deletions(-) diff --git a/tests/baselines/reference/unknownType1.errors.txt b/tests/baselines/reference/unknownType1.errors.txt index c3d5f891fb0..6799941a444 100644 --- a/tests/baselines/reference/unknownType1.errors.txt +++ b/tests/baselines/reference/unknownType1.errors.txt @@ -21,16 +21,18 @@ tests/cases/conformance/types/unknown/unknownType1.ts(120,9): error TS2322: Type tests/cases/conformance/types/unknown/unknownType1.ts(128,5): error TS2322: Type 'number[]' is not assignable to type '{ [x: string]: unknown; }'. Index signature is missing in type 'number[]'. tests/cases/conformance/types/unknown/unknownType1.ts(129,5): error TS2322: Type '123' is not assignable to type '{ [x: string]: unknown; }'. -tests/cases/conformance/types/unknown/unknownType1.ts(149,17): error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value. -tests/cases/conformance/types/unknown/unknownType1.ts(155,14): error TS2700: Rest types may only be created from object types. -tests/cases/conformance/types/unknown/unknownType1.ts(161,5): error TS2564: Property 'a' has no initializer and is not definitely assigned in the constructor. -tests/cases/conformance/types/unknown/unknownType1.ts(170,9): error TS2322: Type 'U' is not assignable to type '{}'. +tests/cases/conformance/types/unknown/unknownType1.ts(143,29): error TS2698: Spread types may only be created from object types. +tests/cases/conformance/types/unknown/unknownType1.ts(144,29): error TS2698: Spread types may only be created from object types. +tests/cases/conformance/types/unknown/unknownType1.ts(150,17): error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value. +tests/cases/conformance/types/unknown/unknownType1.ts(156,14): error TS2700: Rest types may only be created from object types. +tests/cases/conformance/types/unknown/unknownType1.ts(162,5): error TS2564: Property 'a' has no initializer and is not definitely assigned in the constructor. +tests/cases/conformance/types/unknown/unknownType1.ts(171,9): error TS2322: Type 'U' is not assignable to type '{}'. Type 'unknown' is not assignable to type '{}'. -tests/cases/conformance/types/unknown/unknownType1.ts(180,5): error TS2322: Type 'T' is not assignable to type '{}'. +tests/cases/conformance/types/unknown/unknownType1.ts(181,5): error TS2322: Type 'T' is not assignable to type '{}'. Type 'unknown' is not assignable to type '{}'. -==== tests/cases/conformance/types/unknown/unknownType1.ts (25 errors) ==== +==== tests/cases/conformance/types/unknown/unknownType1.ts (27 errors) ==== // In an intersection everything absorbs unknown type T00 = unknown & null; // null @@ -217,7 +219,12 @@ tests/cases/conformance/types/unknown/unknownType1.ts(180,5): error TS2322: Type function f26(x: {}, y: unknown, z: any) { let o1 = { a: 42, ...x }; // { a: number } let o2 = { a: 42, ...x, ...y }; // unknown + ~~~~ +!!! error TS2698: Spread types may only be created from object types. let o3 = { a: 42, ...x, ...y, ...z }; // any + ~~~~ +!!! error TS2698: Spread types may only be created from object types. + let o4 = { a: 42, ...z }; // any } // Functions with unknown return type don't need return expressions diff --git a/tests/baselines/reference/unknownType1.js b/tests/baselines/reference/unknownType1.js index 8bd340de020..efba0af95d0 100644 --- a/tests/baselines/reference/unknownType1.js +++ b/tests/baselines/reference/unknownType1.js @@ -143,6 +143,7 @@ function f26(x: {}, y: unknown, z: any) { let o1 = { a: 42, ...x }; // { a: number } let o2 = { a: 42, ...x, ...y }; // unknown let o3 = { a: 42, ...x, ...y, ...z }; // any + let o4 = { a: 42, ...z }; // any } // Functions with unknown return type don't need return expressions @@ -281,6 +282,7 @@ function f26(x, y, z) { var o1 = __assign({ a: 42 }, x); // { a: number } var o2 = __assign(__assign({ a: 42 }, x), y); // unknown var o3 = __assign(__assign(__assign({ a: 42 }, x), y), z); // any + var o4 = __assign({ a: 42 }, z); // any } // Functions with unknown return type don't need return expressions function f27() { diff --git a/tests/baselines/reference/unknownType1.symbols b/tests/baselines/reference/unknownType1.symbols index 95a3587baab..01c61a925f7 100644 --- a/tests/baselines/reference/unknownType1.symbols +++ b/tests/baselines/reference/unknownType1.symbols @@ -372,82 +372,87 @@ function f26(x: {}, y: unknown, z: any) { >a : Symbol(a, Decl(unknownType1.ts, 143, 14)) >x : Symbol(x, Decl(unknownType1.ts, 140, 13)) >y : Symbol(y, Decl(unknownType1.ts, 140, 19)) +>z : Symbol(z, Decl(unknownType1.ts, 140, 31)) + + let o4 = { a: 42, ...z }; // any +>o4 : Symbol(o4, Decl(unknownType1.ts, 144, 7)) +>a : Symbol(a, Decl(unknownType1.ts, 144, 14)) >z : Symbol(z, Decl(unknownType1.ts, 140, 31)) } // Functions with unknown return type don't need return expressions function f27(): unknown { ->f27 : Symbol(f27, Decl(unknownType1.ts, 144, 1)) +>f27 : Symbol(f27, Decl(unknownType1.ts, 145, 1)) } // Rest type cannot be created from unknown function f28(x: unknown) { ->f28 : Symbol(f28, Decl(unknownType1.ts, 149, 1)) ->x : Symbol(x, Decl(unknownType1.ts, 153, 13)) +>f28 : Symbol(f28, Decl(unknownType1.ts, 150, 1)) +>x : Symbol(x, Decl(unknownType1.ts, 154, 13)) let { ...a } = x; // Error ->a : Symbol(a, Decl(unknownType1.ts, 154, 9)) ->x : Symbol(x, Decl(unknownType1.ts, 153, 13)) +>a : Symbol(a, Decl(unknownType1.ts, 155, 9)) +>x : Symbol(x, Decl(unknownType1.ts, 154, 13)) } // Class properties of type unknown don't need definite assignment class C1 { ->C1 : Symbol(C1, Decl(unknownType1.ts, 155, 1)) +>C1 : Symbol(C1, Decl(unknownType1.ts, 156, 1)) a: string; // Error ->a : Symbol(C1.a, Decl(unknownType1.ts, 159, 10)) +>a : Symbol(C1.a, Decl(unknownType1.ts, 160, 10)) b: unknown; ->b : Symbol(C1.b, Decl(unknownType1.ts, 160, 14)) +>b : Symbol(C1.b, Decl(unknownType1.ts, 161, 14)) c: any; ->c : Symbol(C1.c, Decl(unknownType1.ts, 161, 15)) +>c : Symbol(C1.c, Decl(unknownType1.ts, 162, 15)) } // Type parameter with explicit 'unknown' constraint not assignable to '{}' function f30(t: T, u: U) { ->f30 : Symbol(f30, Decl(unknownType1.ts, 163, 1)) ->T : Symbol(T, Decl(unknownType1.ts, 167, 13)) ->U : Symbol(U, Decl(unknownType1.ts, 167, 15)) ->t : Symbol(t, Decl(unknownType1.ts, 167, 35)) ->T : Symbol(T, Decl(unknownType1.ts, 167, 13)) ->u : Symbol(u, Decl(unknownType1.ts, 167, 40)) ->U : Symbol(U, Decl(unknownType1.ts, 167, 15)) +>f30 : Symbol(f30, Decl(unknownType1.ts, 164, 1)) +>T : Symbol(T, Decl(unknownType1.ts, 168, 13)) +>U : Symbol(U, Decl(unknownType1.ts, 168, 15)) +>t : Symbol(t, Decl(unknownType1.ts, 168, 35)) +>T : Symbol(T, Decl(unknownType1.ts, 168, 13)) +>u : Symbol(u, Decl(unknownType1.ts, 168, 40)) +>U : Symbol(U, Decl(unknownType1.ts, 168, 15)) let x: {} = t; ->x : Symbol(x, Decl(unknownType1.ts, 168, 7)) ->t : Symbol(t, Decl(unknownType1.ts, 167, 35)) +>x : Symbol(x, Decl(unknownType1.ts, 169, 7)) +>t : Symbol(t, Decl(unknownType1.ts, 168, 35)) let y: {} = u; ->y : Symbol(y, Decl(unknownType1.ts, 169, 7)) ->u : Symbol(u, Decl(unknownType1.ts, 167, 40)) +>y : Symbol(y, Decl(unknownType1.ts, 170, 7)) +>u : Symbol(u, Decl(unknownType1.ts, 168, 40)) } // Repro from #26796 type Test1 = [unknown] extends [{}] ? true : false; // false ->Test1 : Symbol(Test1, Decl(unknownType1.ts, 170, 1)) +>Test1 : Symbol(Test1, Decl(unknownType1.ts, 171, 1)) type IsDefinitelyDefined = [T] extends [{}] ? true : false; ->IsDefinitelyDefined : Symbol(IsDefinitelyDefined, Decl(unknownType1.ts, 174, 51)) ->T : Symbol(T, Decl(unknownType1.ts, 175, 25)) ->T : Symbol(T, Decl(unknownType1.ts, 175, 25)) +>IsDefinitelyDefined : Symbol(IsDefinitelyDefined, Decl(unknownType1.ts, 175, 51)) +>T : Symbol(T, Decl(unknownType1.ts, 176, 25)) +>T : Symbol(T, Decl(unknownType1.ts, 176, 25)) type Test2 = IsDefinitelyDefined; // false ->Test2 : Symbol(Test2, Decl(unknownType1.ts, 175, 78)) ->IsDefinitelyDefined : Symbol(IsDefinitelyDefined, Decl(unknownType1.ts, 174, 51)) +>Test2 : Symbol(Test2, Decl(unknownType1.ts, 176, 78)) +>IsDefinitelyDefined : Symbol(IsDefinitelyDefined, Decl(unknownType1.ts, 175, 51)) function oops(arg: T): {} { ->oops : Symbol(oops, Decl(unknownType1.ts, 176, 42)) ->T : Symbol(T, Decl(unknownType1.ts, 178, 14)) ->arg : Symbol(arg, Decl(unknownType1.ts, 178, 33)) ->T : Symbol(T, Decl(unknownType1.ts, 178, 14)) +>oops : Symbol(oops, Decl(unknownType1.ts, 177, 42)) +>T : Symbol(T, Decl(unknownType1.ts, 179, 14)) +>arg : Symbol(arg, Decl(unknownType1.ts, 179, 33)) +>T : Symbol(T, Decl(unknownType1.ts, 179, 14)) return arg; // Error ->arg : Symbol(arg, Decl(unknownType1.ts, 178, 33)) +>arg : Symbol(arg, Decl(unknownType1.ts, 179, 33)) } diff --git a/tests/baselines/reference/unknownType1.types b/tests/baselines/reference/unknownType1.types index 7d284681698..c6911e0bf3b 100644 --- a/tests/baselines/reference/unknownType1.types +++ b/tests/baselines/reference/unknownType1.types @@ -404,8 +404,8 @@ function f26(x: {}, y: unknown, z: any) { >x : {} let o2 = { a: 42, ...x, ...y }; // unknown ->o2 : unknown ->{ a: 42, ...x, ...y } : unknown +>o2 : any +>{ a: 42, ...x, ...y } : any >a : number >42 : 42 >x : {} @@ -418,6 +418,13 @@ function f26(x: {}, y: unknown, z: any) { >42 : 42 >x : {} >y : unknown +>z : any + + let o4 = { a: 42, ...z }; // any +>o4 : any +>{ a: 42, ...z } : any +>a : number +>42 : 42 >z : any } diff --git a/tests/cases/conformance/types/unknown/unknownType1.ts b/tests/cases/conformance/types/unknown/unknownType1.ts index f96d1bb32c6..e207a4586bd 100644 --- a/tests/cases/conformance/types/unknown/unknownType1.ts +++ b/tests/cases/conformance/types/unknown/unknownType1.ts @@ -144,6 +144,7 @@ function f26(x: {}, y: unknown, z: any) { let o1 = { a: 42, ...x }; // { a: number } let o2 = { a: 42, ...x, ...y }; // unknown let o3 = { a: 42, ...x, ...y, ...z }; // any + let o4 = { a: 42, ...z }; // any } // Functions with unknown return type don't need return expressions From 5ae286329f254a9b5fed1dd2d2208f76d9b7e011 Mon Sep 17 00:00:00 2001 From: falsandtru Date: Tue, 20 Aug 2019 01:10:12 +0900 Subject: [PATCH 03/10] Update String#toLocale{Lower,Upper}Case methods (#32961) --- src/lib/es5.d.ts | 4 ++-- .../reference/destructuringWithGenericParameter.types | 4 ++-- tests/baselines/reference/typeGuardsOnClassProperty.types | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/lib/es5.d.ts b/src/lib/es5.d.ts index 819c69a3fc4..3eced36c077 100644 --- a/src/lib/es5.d.ts +++ b/src/lib/es5.d.ts @@ -466,13 +466,13 @@ interface String { toLowerCase(): string; /** Converts all alphabetic characters to lowercase, taking into account the host environment's current locale. */ - toLocaleLowerCase(): string; + toLocaleLowerCase(locales?: string | string[]): string; /** Converts all the alphabetic characters in a string to uppercase. */ toUpperCase(): string; /** Returns a string where all alphabetic characters have been converted to uppercase, taking into account the host environment's current locale. */ - toLocaleUpperCase(): string; + toLocaleUpperCase(locales?: string | string[]): string; /** Removes the leading and trailing white space and line terminator characters from a string. */ trim(): string; diff --git a/tests/baselines/reference/destructuringWithGenericParameter.types b/tests/baselines/reference/destructuringWithGenericParameter.types index 7cf2b8f00ae..e5895a55deb 100644 --- a/tests/baselines/reference/destructuringWithGenericParameter.types +++ b/tests/baselines/reference/destructuringWithGenericParameter.types @@ -36,9 +36,9 @@ genericFunction(genericObject, ({greeting}) => { var s = greeting.toLocaleLowerCase(); // Greeting should be of type string >s : string >greeting.toLocaleLowerCase() : string ->greeting.toLocaleLowerCase : () => string +>greeting.toLocaleLowerCase : (locales?: string | string[]) => string >greeting : string ->toLocaleLowerCase : () => string +>toLocaleLowerCase : (locales?: string | string[]) => string }); diff --git a/tests/baselines/reference/typeGuardsOnClassProperty.types b/tests/baselines/reference/typeGuardsOnClassProperty.types index 6a79412237a..0c68086ab62 100644 --- a/tests/baselines/reference/typeGuardsOnClassProperty.types +++ b/tests/baselines/reference/typeGuardsOnClassProperty.types @@ -106,7 +106,7 @@ if (typeof prop1 === "string" && prop1.toLocaleLowerCase()) { } >prop1 : string | number >"string" : "string" >prop1.toLocaleLowerCase() : string ->prop1.toLocaleLowerCase : () => string +>prop1.toLocaleLowerCase : (locales?: string | string[]) => string >prop1 : string ->toLocaleLowerCase : () => string +>toLocaleLowerCase : (locales?: string | string[]) => string From 9e9e69436930c51ebb5f2e185f71603b5b029c96 Mon Sep 17 00:00:00 2001 From: Wes Souza Date: Mon, 19 Aug 2019 12:42:49 -0400 Subject: [PATCH 04/10] Update Feature_request.md (#32974) * Update Feature_request.md Added the same list of steps that is present on the bug report to the feature request. * Remove duplicate FAQ reading sentence --- .github/ISSUE_TEMPLATE/Feature_request.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/Feature_request.md b/.github/ISSUE_TEMPLATE/Feature_request.md index f40965f503a..74525bf2f80 100644 --- a/.github/ISSUE_TEMPLATE/Feature_request.md +++ b/.github/ISSUE_TEMPLATE/Feature_request.md @@ -6,7 +6,11 @@ about: Suggest an idea for this project From 2cde3b722ae458a6e57ed9ab9cea8c67d43e13e8 Mon Sep 17 00:00:00 2001 From: TypeScript Bot Date: Mon, 19 Aug 2019 10:46:30 -0700 Subject: [PATCH 05/10] Update user baselines (#32975) --- .../reference/user/TypeScript-Node-Starter.log | 12 ------------ tests/cases/user/puppeteer/puppeteer | 2 +- tests/cases/user/webpack/webpack | 2 +- 3 files changed, 2 insertions(+), 14 deletions(-) delete mode 100644 tests/baselines/reference/user/TypeScript-Node-Starter.log diff --git a/tests/baselines/reference/user/TypeScript-Node-Starter.log b/tests/baselines/reference/user/TypeScript-Node-Starter.log deleted file mode 100644 index f26c48b3100..00000000000 --- a/tests/baselines/reference/user/TypeScript-Node-Starter.log +++ /dev/null @@ -1,12 +0,0 @@ -Exit Code: 1 -Standard output: -src/controllers/user.ts(210,33): error TS2339: Property 'provider' does not exist on type 'Params'. - Property 'provider' does not exist on type 'string[]'. -src/controllers/user.ts(232,51): error TS2339: Property 'token' does not exist on type 'Params'. - Property 'token' does not exist on type 'string[]'. -src/controllers/user.ts(264,59): error TS2339: Property 'token' does not exist on type 'Params'. - Property 'token' does not exist on type 'string[]'. - - - -Standard error: diff --git a/tests/cases/user/puppeteer/puppeteer b/tests/cases/user/puppeteer/puppeteer index 498492d4a3c..faa452718e5 160000 --- a/tests/cases/user/puppeteer/puppeteer +++ b/tests/cases/user/puppeteer/puppeteer @@ -1 +1 @@ -Subproject commit 498492d4a3c63924e3325cf2d9f9d27d920c73a4 +Subproject commit faa452718e5b257ffe262f410e52f676b6587e80 diff --git a/tests/cases/user/webpack/webpack b/tests/cases/user/webpack/webpack index 8748eee7f8d..3675f64e518 160000 --- a/tests/cases/user/webpack/webpack +++ b/tests/cases/user/webpack/webpack @@ -1 +1 @@ -Subproject commit 8748eee7f8d65bc5eb62ed74a9db82c5d8518b6e +Subproject commit 3675f64e518c358c22e044624787ad0446e59cf9 From d9f021232486f354278ccdfb605a3decfa0dc823 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Mon, 19 Aug 2019 11:31:47 -0700 Subject: [PATCH 06/10] Resolve SymbolFlags.Type only at first in jsdoc getTypeFromTypeReference (#32947) * Fix lookup of exported eunm type alias in local scope in JS * Fix by adjusting type lookup fallback behavior to not include SymbolFlags.Value in its initial lookup instead --- src/compiler/checker.ts | 17 ++- .../reference/jsEnumTagOnObjectFrozen.symbols | 86 +++++++++++++++ .../reference/jsEnumTagOnObjectFrozen.types | 101 ++++++++++++++++++ .../cases/compiler/jsEnumTagOnObjectFrozen.ts | 45 ++++++++ .../user/create-react-app/create-react-app | 2 +- tests/cases/user/puppeteer/puppeteer | 2 +- tests/cases/user/webpack/webpack | 2 +- 7 files changed, 248 insertions(+), 7 deletions(-) create mode 100644 tests/baselines/reference/jsEnumTagOnObjectFrozen.symbols create mode 100644 tests/baselines/reference/jsEnumTagOnObjectFrozen.types create mode 100644 tests/cases/compiler/jsEnumTagOnObjectFrozen.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 53f96d507b8..478c7b46075 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -9165,12 +9165,12 @@ namespace ts { return undefined; } - function resolveTypeReferenceName(typeReferenceName: EntityNameExpression | EntityName | undefined, meaning: SymbolFlags) { + function resolveTypeReferenceName(typeReferenceName: EntityNameExpression | EntityName | undefined, meaning: SymbolFlags, ignoreErrors?: boolean) { if (!typeReferenceName) { return unknownSymbol; } - return resolveEntityName(typeReferenceName, meaning) || unknownSymbol; + return resolveEntityName(typeReferenceName, meaning, ignoreErrors) || unknownSymbol; } function getTypeReferenceType(node: NodeWithTypeArguments, symbol: Symbol): Type { @@ -9362,10 +9362,19 @@ namespace ts { if (!links.resolvedType) { let symbol: Symbol | undefined; let type: Type | undefined; - let meaning = SymbolFlags.Type; + const meaning = SymbolFlags.Type; if (isJSDocTypeReference(node)) { type = getIntendedTypeFromJSDocTypeReference(node); - meaning |= SymbolFlags.Value; + if (!type) { + symbol = resolveTypeReferenceName(getTypeReferenceName(node), meaning, /*ignoreErrors*/ true); + if (symbol === unknownSymbol) { + symbol = resolveTypeReferenceName(getTypeReferenceName(node), meaning | SymbolFlags.Value); + } + else { + resolveTypeReferenceName(getTypeReferenceName(node), meaning); // Resolve again to mark errors, if any + } + type = getTypeReferenceType(node, symbol); + } } if (!type) { symbol = resolveTypeReferenceName(getTypeReferenceName(node), meaning); diff --git a/tests/baselines/reference/jsEnumTagOnObjectFrozen.symbols b/tests/baselines/reference/jsEnumTagOnObjectFrozen.symbols new file mode 100644 index 00000000000..32a9543fbf7 --- /dev/null +++ b/tests/baselines/reference/jsEnumTagOnObjectFrozen.symbols @@ -0,0 +1,86 @@ +=== tests/cases/compiler/usage.js === +const { Thing, useThing, cbThing } = require("./index"); +>Thing : Symbol(Thing, Decl(usage.js, 0, 7)) +>useThing : Symbol(useThing, Decl(usage.js, 0, 14)) +>cbThing : Symbol(cbThing, Decl(usage.js, 0, 24)) +>require : Symbol(require) +>"./index" : Symbol("tests/cases/compiler/index", Decl(index.js, 0, 0)) + +useThing(Thing.a); +>useThing : Symbol(useThing, Decl(usage.js, 0, 14)) +>Thing : Symbol(Thing, Decl(usage.js, 0, 7)) + +/** + * @typedef {Object} LogEntry + * @property {string} type + * @property {number} time + */ + +cbThing(type => { +>cbThing : Symbol(cbThing, Decl(usage.js, 0, 24)) +>type : Symbol(type, Decl(usage.js, 10, 8)) + + /** @type {LogEntry} */ + const logEntry = { +>logEntry : Symbol(logEntry, Decl(usage.js, 12, 9)) + + time: Date.now(), +>time : Symbol(time, Decl(usage.js, 12, 22)) +>Date.now : Symbol(DateConstructor.now, Decl(lib.es5.d.ts, --, --)) +>Date : Symbol(Date, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.scripthost.d.ts, --, --)) +>now : Symbol(DateConstructor.now, Decl(lib.es5.d.ts, --, --)) + + type, +>type : Symbol(type, Decl(usage.js, 13, 25)) + + }; +}); + +=== tests/cases/compiler/index.js === +/** @enum {string} */ +const Thing = Object.freeze({ +>Thing : Symbol(Thing, Decl(index.js, 1, 5), Decl(index.js, 0, 4)) +>Object.freeze : Symbol(ObjectConstructor.freeze, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>freeze : Symbol(ObjectConstructor.freeze, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + + a: "thing", +>a : Symbol(a, Decl(index.js, 1, 29)) + + b: "chill" +>b : Symbol(b, Decl(index.js, 2, 15)) + +}); + +exports.Thing = Thing; +>exports.Thing : Symbol(Thing, Decl(index.js, 4, 3), Decl(index.js, 0, 4)) +>exports : Symbol(Thing, Decl(index.js, 4, 3), Decl(index.js, 0, 4)) +>Thing : Symbol(Thing, Decl(index.js, 4, 3), Decl(index.js, 0, 4)) +>Thing : Symbol(Thing, Decl(index.js, 1, 5), Decl(index.js, 0, 4)) + +/** + * @param {Thing} x + */ +function useThing(x) {} +>useThing : Symbol(useThing, Decl(index.js, 6, 22)) +>x : Symbol(x, Decl(index.js, 11, 18)) + +exports.useThing = useThing; +>exports.useThing : Symbol(useThing, Decl(index.js, 11, 23)) +>exports : Symbol(useThing, Decl(index.js, 11, 23)) +>useThing : Symbol(useThing, Decl(index.js, 11, 23)) +>useThing : Symbol(useThing, Decl(index.js, 6, 22)) + +/** + * @param {(x: Thing) => void} x + */ +function cbThing(x) {} +>cbThing : Symbol(cbThing, Decl(index.js, 13, 28)) +>x : Symbol(x, Decl(index.js, 18, 17)) + +exports.cbThing = cbThing; +>exports.cbThing : Symbol(cbThing, Decl(index.js, 18, 22)) +>exports : Symbol(cbThing, Decl(index.js, 18, 22)) +>cbThing : Symbol(cbThing, Decl(index.js, 18, 22)) +>cbThing : Symbol(cbThing, Decl(index.js, 13, 28)) + diff --git a/tests/baselines/reference/jsEnumTagOnObjectFrozen.types b/tests/baselines/reference/jsEnumTagOnObjectFrozen.types new file mode 100644 index 00000000000..df50c0635e2 --- /dev/null +++ b/tests/baselines/reference/jsEnumTagOnObjectFrozen.types @@ -0,0 +1,101 @@ +=== tests/cases/compiler/usage.js === +const { Thing, useThing, cbThing } = require("./index"); +>Thing : any +>useThing : (x: string) => void +>cbThing : (x: (x: string) => void) => void +>require("./index") : typeof import("tests/cases/compiler/index") +>require : any +>"./index" : "./index" + +useThing(Thing.a); +>useThing(Thing.a) : void +>useThing : (x: string) => void +>Thing.a : error +>Thing : any +>a : any + +/** + * @typedef {Object} LogEntry + * @property {string} type + * @property {number} time + */ + +cbThing(type => { +>cbThing(type => { /** @type {LogEntry} */ const logEntry = { time: Date.now(), type, };}) : void +>cbThing : (x: (x: string) => void) => void +>type => { /** @type {LogEntry} */ const logEntry = { time: Date.now(), type, };} : (type: string) => void +>type : string + + /** @type {LogEntry} */ + const logEntry = { +>logEntry : LogEntry +>{ time: Date.now(), type, } : { time: number; type: string; } + + time: Date.now(), +>time : number +>Date.now() : number +>Date.now : () => number +>Date : DateConstructor +>now : () => number + + type, +>type : string + + }; +}); + +=== tests/cases/compiler/index.js === +/** @enum {string} */ +const Thing = Object.freeze({ +>Thing : Readonly<{ a: string; b: string; }> +>Object.freeze({ a: "thing", b: "chill"}) : Readonly<{ a: string; b: string; }> +>Object.freeze : { (a: T[]): readonly T[]; (f: T): T; (o: T): Readonly; } +>Object : ObjectConstructor +>freeze : { (a: T[]): readonly T[]; (f: T): T; (o: T): Readonly; } +>{ a: "thing", b: "chill"} : { a: string; b: string; } + + a: "thing", +>a : string +>"thing" : "thing" + + b: "chill" +>b : string +>"chill" : "chill" + +}); + +exports.Thing = Thing; +>exports.Thing = Thing : Readonly<{ a: string; b: string; }> +>exports.Thing : error +>exports : typeof import("tests/cases/compiler/index") +>Thing : any +>Thing : Readonly<{ a: string; b: string; }> + +/** + * @param {Thing} x + */ +function useThing(x) {} +>useThing : (x: string) => void +>x : string + +exports.useThing = useThing; +>exports.useThing = useThing : (x: string) => void +>exports.useThing : (x: string) => void +>exports : typeof import("tests/cases/compiler/index") +>useThing : (x: string) => void +>useThing : (x: string) => void + +/** + * @param {(x: Thing) => void} x + */ +function cbThing(x) {} +>cbThing : (x: (x: string) => void) => void +>x : (x: string) => void + +exports.cbThing = cbThing; +>exports.cbThing = cbThing : (x: (x: string) => void) => void +>exports.cbThing : (x: (x: string) => void) => void +>exports : typeof import("tests/cases/compiler/index") +>cbThing : (x: (x: string) => void) => void +>cbThing : (x: (x: string) => void) => void + diff --git a/tests/cases/compiler/jsEnumTagOnObjectFrozen.ts b/tests/cases/compiler/jsEnumTagOnObjectFrozen.ts new file mode 100644 index 00000000000..a8414d68ad7 --- /dev/null +++ b/tests/cases/compiler/jsEnumTagOnObjectFrozen.ts @@ -0,0 +1,45 @@ +// @noEmit: true +// @checkJs: true +// @allowJs: true +// @filename: index.js +/** @enum {string} */ +const Thing = Object.freeze({ + a: "thing", + b: "chill" +}); + +exports.Thing = Thing; + +/** + * @param {Thing} x + */ +function useThing(x) {} + +exports.useThing = useThing; + +/** + * @param {(x: Thing) => void} x + */ +function cbThing(x) {} + +exports.cbThing = cbThing; + +// @filename: usage.js + +const { Thing, useThing, cbThing } = require("./index"); + +useThing(Thing.a); + +/** + * @typedef {Object} LogEntry + * @property {string} type + * @property {number} time + */ + +cbThing(type => { + /** @type {LogEntry} */ + const logEntry = { + time: Date.now(), + type, + }; +}); diff --git a/tests/cases/user/create-react-app/create-react-app b/tests/cases/user/create-react-app/create-react-app index 24780bbc608..437b83f0337 160000 --- a/tests/cases/user/create-react-app/create-react-app +++ b/tests/cases/user/create-react-app/create-react-app @@ -1 +1 @@ -Subproject commit 24780bbc608810d874575791bffeb0148e311fef +Subproject commit 437b83f0337a5d57ce7dd976d2c3b44cb2037e45 diff --git a/tests/cases/user/puppeteer/puppeteer b/tests/cases/user/puppeteer/puppeteer index faa452718e5..b6b29502eb6 160000 --- a/tests/cases/user/puppeteer/puppeteer +++ b/tests/cases/user/puppeteer/puppeteer @@ -1 +1 @@ -Subproject commit faa452718e5b257ffe262f410e52f676b6587e80 +Subproject commit b6b29502eb6a75fe3869806f0e7b27195fe51b0d diff --git a/tests/cases/user/webpack/webpack b/tests/cases/user/webpack/webpack index 3675f64e518..743ae6da9a6 160000 --- a/tests/cases/user/webpack/webpack +++ b/tests/cases/user/webpack/webpack @@ -1 +1 @@ -Subproject commit 3675f64e518c358c22e044624787ad0446e59cf9 +Subproject commit 743ae6da9a6fc3b459a7ab3bb250fb07d14f9c5d From d75de605480f9d1c91d43e8a70d3913c31172956 Mon Sep 17 00:00:00 2001 From: rChaser53 Date: Tue, 20 Aug 2019 04:08:34 +0900 Subject: [PATCH 07/10] Fix Cannot read property 'text' of undefined crash (#32734) * Fix Cannot read property 'text' of undefined crash * fix condition for tsx * Rename and improve the method --- src/compiler/checker.ts | 12 ++++++++---- .../reference/errorElaboration.errors.txt | 19 ++++++++++++++++++- tests/baselines/reference/errorElaboration.js | 11 +++++++++++ .../reference/errorElaboration.symbols | 12 ++++++++++++ .../reference/errorElaboration.types | 17 +++++++++++++++++ tests/cases/compiler/errorElaboration.ts | 5 +++++ 6 files changed, 71 insertions(+), 5 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 478c7b46075..7f7e36cb1f6 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3525,8 +3525,8 @@ namespace ts { } function getTypeNamesForErrorDisplay(left: Type, right: Type): [string, string] { - let leftStr = typeToString(left); - let rightStr = typeToString(right); + let leftStr = symbolValueDeclarationIsContextSensitive(left.symbol) ? typeToString(left, left.symbol.valueDeclaration) : typeToString(left); + let rightStr = symbolValueDeclarationIsContextSensitive(right.symbol) ? typeToString(right, right.symbol.valueDeclaration) : typeToString(right); if (leftStr === rightStr) { leftStr = typeToString(left, /*enclosingDeclaration*/ undefined, TypeFormatFlags.UseFullyQualifiedType); rightStr = typeToString(right, /*enclosingDeclaration*/ undefined, TypeFormatFlags.UseFullyQualifiedType); @@ -3534,6 +3534,10 @@ namespace ts { return [leftStr, rightStr]; } + function symbolValueDeclarationIsContextSensitive(symbol: Symbol): boolean { + return symbol && symbol.valueDeclaration && isExpression(symbol.valueDeclaration) && !isContextSensitive(symbol.valueDeclaration); + } + function toNodeBuilderFlags(flags = TypeFormatFlags.None): NodeBuilderFlags { return flags & TypeFormatFlags.NodeBuilderFlagsMask; } @@ -12718,8 +12722,8 @@ namespace ts { } function tryElaborateErrorsForPrimitivesAndObjects(source: Type, target: Type) { - const sourceType = typeToString(source); - const targetType = typeToString(target); + const sourceType = symbolValueDeclarationIsContextSensitive(source.symbol) ? typeToString(source, source.symbol.valueDeclaration) : typeToString(source); + const targetType = symbolValueDeclarationIsContextSensitive(target.symbol) ? typeToString(target, target.symbol.valueDeclaration) : typeToString(target); if ((globalStringType === source && stringType === target) || (globalNumberType === source && numberType === target) || diff --git a/tests/baselines/reference/errorElaboration.errors.txt b/tests/baselines/reference/errorElaboration.errors.txt index 57971cad269..30c4fe8efd6 100644 --- a/tests/baselines/reference/errorElaboration.errors.txt +++ b/tests/baselines/reference/errorElaboration.errors.txt @@ -1,11 +1,15 @@ +tests/cases/compiler/errorElaboration.ts(10,18): error TS2300: Duplicate identifier 'foo'. tests/cases/compiler/errorElaboration.ts(12,5): error TS2345: Argument of type '() => Container>' is not assignable to parameter of type '() => Container>'. Type 'Container>' is not assignable to type 'Container>'. Type 'Ref' is not assignable to type 'Ref'. Type 'string' is not assignable to type 'number'. tests/cases/compiler/errorElaboration.ts(17,11): error TS2322: Type '"bar"' is not assignable to type '"foo"'. +tests/cases/compiler/errorElaboration.ts(22,7): error TS2300: Duplicate identifier 'foo'. +tests/cases/compiler/errorElaboration.ts(23,15): error TS2538: Type 'any' cannot be used as an index type. +tests/cases/compiler/errorElaboration.ts(23,19): error TS2339: Property 'bar' does not exist on type '(x: () => Container>) => void'. -==== tests/cases/compiler/errorElaboration.ts (2 errors) ==== +==== tests/cases/compiler/errorElaboration.ts (6 errors) ==== // Repro for #5712 interface Ref { @@ -16,6 +20,8 @@ tests/cases/compiler/errorElaboration.ts(17,11): error TS2322: Type '"bar"' is n m2: T; } declare function foo(x: () => Container>): void; + ~~~ +!!! error TS2300: Duplicate identifier 'foo'. let a: () => Container>; foo(a); ~ @@ -32,4 +38,15 @@ tests/cases/compiler/errorElaboration.ts(17,11): error TS2322: Type '"bar"' is n !!! error TS2322: Type '"bar"' is not assignable to type '"foo"'. !!! related TS6500 tests/cases/compiler/errorElaboration.ts:16:18: The expected type comes from property 'foo' which is declared here on type '{ foo: "foo"; }' } + + // Repro for #32358 + + const foo = { bar: 'a' }; + ~~~ +!!! error TS2300: Duplicate identifier 'foo'. + const x = ({ [foo.bar]: c }) => undefined; + ~~~~~~~ +!!! error TS2538: Type 'any' cannot be used as an index type. + ~~~ +!!! error TS2339: Property 'bar' does not exist on type '(x: () => Container>) => void'. \ No newline at end of file diff --git a/tests/baselines/reference/errorElaboration.js b/tests/baselines/reference/errorElaboration.js index c1dd0a470d3..f5e021363e9 100644 --- a/tests/baselines/reference/errorElaboration.js +++ b/tests/baselines/reference/errorElaboration.js @@ -17,6 +17,11 @@ foo(a); function test(): {[A in "foo"]: A} { return {foo: "bar"}; } + +// Repro for #32358 + +const foo = { bar: 'a' }; +const x = ({ [foo.bar]: c }) => undefined; //// [errorElaboration.js] @@ -27,3 +32,9 @@ foo(a); function test() { return { foo: "bar" }; } +// Repro for #32358 +var foo = { bar: 'a' }; +var x = function (_a) { + var _b = foo.bar, c = _a[_b]; + return undefined; +}; diff --git a/tests/baselines/reference/errorElaboration.symbols b/tests/baselines/reference/errorElaboration.symbols index 839b19c0599..407fc9b2568 100644 --- a/tests/baselines/reference/errorElaboration.symbols +++ b/tests/baselines/reference/errorElaboration.symbols @@ -49,3 +49,15 @@ function test(): {[A in "foo"]: A} { >foo : Symbol(foo, Decl(errorElaboration.ts, 16, 10)) } +// Repro for #32358 + +const foo = { bar: 'a' }; +>foo : Symbol(foo, Decl(errorElaboration.ts, 21, 5)) +>bar : Symbol(bar, Decl(errorElaboration.ts, 21, 13)) + +const x = ({ [foo.bar]: c }) => undefined; +>x : Symbol(x, Decl(errorElaboration.ts, 22, 5)) +>foo : Symbol(foo, Decl(errorElaboration.ts, 8, 1)) +>c : Symbol(c, Decl(errorElaboration.ts, 22, 12)) +>undefined : Symbol(undefined) + diff --git a/tests/baselines/reference/errorElaboration.types b/tests/baselines/reference/errorElaboration.types index d46222071f4..6957a9f48b1 100644 --- a/tests/baselines/reference/errorElaboration.types +++ b/tests/baselines/reference/errorElaboration.types @@ -35,3 +35,20 @@ function test(): {[A in "foo"]: A} { >"bar" : "bar" } +// Repro for #32358 + +const foo = { bar: 'a' }; +>foo : { bar: string; } +>{ bar: 'a' } : { bar: string; } +>bar : string +>'a' : "a" + +const x = ({ [foo.bar]: c }) => undefined; +>x : ({ [foo.bar]: c }: {}) => any +>({ [foo.bar]: c }) => undefined : ({ [foo.bar]: c }: {}) => any +>foo.bar : any +>foo : (x: () => Container>) => void +>bar : any +>c : any +>undefined : undefined + diff --git a/tests/cases/compiler/errorElaboration.ts b/tests/cases/compiler/errorElaboration.ts index 87575f1df11..bea98f7e60a 100644 --- a/tests/cases/compiler/errorElaboration.ts +++ b/tests/cases/compiler/errorElaboration.ts @@ -16,3 +16,8 @@ foo(a); function test(): {[A in "foo"]: A} { return {foo: "bar"}; } + +// Repro for #32358 + +const foo = { bar: 'a' }; +const x = ({ [foo.bar]: c }) => undefined; From fd1e22bbf13ac6596c0df92002df7f767612f7a2 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Mon, 19 Aug 2019 13:01:08 -0700 Subject: [PATCH 08/10] Instantiate generic conditional infer source types in the context of the target conditional (#31545) * Instantiate generic conditional infer source types in the context of the target conditional * Add test case from #26627 --- src/compiler/checker.ts | 14 ++- ...icalGenericConditionalsWithInferRelated.js | 48 +++++++++ ...enericConditionalsWithInferRelated.symbols | 100 ++++++++++++++++++ ...lGenericConditionalsWithInferRelated.types | 65 ++++++++++++ ...icalGenericConditionalsWithInferRelated.ts | 28 +++++ 5 files changed, 253 insertions(+), 2 deletions(-) create mode 100644 tests/baselines/reference/identicalGenericConditionalsWithInferRelated.js create mode 100644 tests/baselines/reference/identicalGenericConditionalsWithInferRelated.symbols create mode 100644 tests/baselines/reference/identicalGenericConditionalsWithInferRelated.types create mode 100644 tests/cases/compiler/identicalGenericConditionalsWithInferRelated.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 7f7e36cb1f6..84e3ed842cf 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13527,9 +13527,19 @@ namespace ts { // Two conditional types 'T1 extends U1 ? X1 : Y1' and 'T2 extends U2 ? X2 : Y2' are related if // one of T1 and T2 is related to the other, U1 and U2 are identical types, X1 is related to X2, // and Y1 is related to Y2. - if (isTypeIdenticalTo((source).extendsType, (target).extendsType) && + const sourceParams = (source as ConditionalType).root.inferTypeParameters; + let sourceExtends = (source).extendsType; + let mapper: TypeMapper | undefined; + if (sourceParams) { + // If the source has infer type parameters, we instantiate them in the context of the target + const ctx = createInferenceContext(sourceParams, /*signature*/ undefined, InferenceFlags.None, isRelatedTo); + inferTypes(ctx.inferences, (target).extendsType, sourceExtends, InferencePriority.NoConstraints | InferencePriority.AlwaysStrict); + sourceExtends = instantiateType(sourceExtends, ctx.mapper); + mapper = ctx.mapper; + } + if (isTypeIdenticalTo(sourceExtends, (target).extendsType) && (isRelatedTo((source).checkType, (target).checkType) || isRelatedTo((target).checkType, (source).checkType))) { - if (result = isRelatedTo(getTrueTypeFromConditionalType(source), getTrueTypeFromConditionalType(target), reportErrors)) { + if (result = isRelatedTo(instantiateType(getTrueTypeFromConditionalType(source), mapper), getTrueTypeFromConditionalType(target), reportErrors)) { result &= isRelatedTo(getFalseTypeFromConditionalType(source), getFalseTypeFromConditionalType(target), reportErrors); } if (result) { diff --git a/tests/baselines/reference/identicalGenericConditionalsWithInferRelated.js b/tests/baselines/reference/identicalGenericConditionalsWithInferRelated.js new file mode 100644 index 00000000000..a4bc95d1eb5 --- /dev/null +++ b/tests/baselines/reference/identicalGenericConditionalsWithInferRelated.js @@ -0,0 +1,48 @@ +//// [identicalGenericConditionalsWithInferRelated.ts] +function f(arg: X) { + type Cond1 = X extends [infer A] ? A : never; + type Cond2 = X extends [infer A] ? A : never; + + let x: Cond1 = null as any; + let y: Cond2 = null as any; + x = y; // is err, should be ok + y = x; // is err, should be ok +} + +// repro from https://github.com/microsoft/TypeScript/issues/26627 +export type Constructor = new (...args: any[]) => T +export type MappedResult = + T extends Boolean ? boolean : + T extends Number ? number : + T extends String ? string : + T + + +interface X { + decode>(ctor: C): MappedResult ? T : never> +} + +class Y implements X { + decode>(ctor: C): MappedResult ? T : never> { + throw new Error() + } +} + + +//// [identicalGenericConditionalsWithInferRelated.js] +"use strict"; +exports.__esModule = true; +function f(arg) { + var x = null; + var y = null; + x = y; // is err, should be ok + y = x; // is err, should be ok +} +var Y = /** @class */ (function () { + function Y() { + } + Y.prototype.decode = function (ctor) { + throw new Error(); + }; + return Y; +}()); diff --git a/tests/baselines/reference/identicalGenericConditionalsWithInferRelated.symbols b/tests/baselines/reference/identicalGenericConditionalsWithInferRelated.symbols new file mode 100644 index 00000000000..bfe0e7f8679 --- /dev/null +++ b/tests/baselines/reference/identicalGenericConditionalsWithInferRelated.symbols @@ -0,0 +1,100 @@ +=== tests/cases/compiler/identicalGenericConditionalsWithInferRelated.ts === +function f(arg: X) { +>f : Symbol(f, Decl(identicalGenericConditionalsWithInferRelated.ts, 0, 0)) +>X : Symbol(X, Decl(identicalGenericConditionalsWithInferRelated.ts, 0, 11)) +>arg : Symbol(arg, Decl(identicalGenericConditionalsWithInferRelated.ts, 0, 14)) +>X : Symbol(X, Decl(identicalGenericConditionalsWithInferRelated.ts, 0, 11)) + + type Cond1 = X extends [infer A] ? A : never; +>Cond1 : Symbol(Cond1, Decl(identicalGenericConditionalsWithInferRelated.ts, 0, 23)) +>X : Symbol(X, Decl(identicalGenericConditionalsWithInferRelated.ts, 0, 11)) +>A : Symbol(A, Decl(identicalGenericConditionalsWithInferRelated.ts, 1, 33)) +>A : Symbol(A, Decl(identicalGenericConditionalsWithInferRelated.ts, 1, 33)) + + type Cond2 = X extends [infer A] ? A : never; +>Cond2 : Symbol(Cond2, Decl(identicalGenericConditionalsWithInferRelated.ts, 1, 49)) +>X : Symbol(X, Decl(identicalGenericConditionalsWithInferRelated.ts, 0, 11)) +>A : Symbol(A, Decl(identicalGenericConditionalsWithInferRelated.ts, 2, 33)) +>A : Symbol(A, Decl(identicalGenericConditionalsWithInferRelated.ts, 2, 33)) + + let x: Cond1 = null as any; +>x : Symbol(x, Decl(identicalGenericConditionalsWithInferRelated.ts, 4, 7)) +>Cond1 : Symbol(Cond1, Decl(identicalGenericConditionalsWithInferRelated.ts, 0, 23)) + + let y: Cond2 = null as any; +>y : Symbol(y, Decl(identicalGenericConditionalsWithInferRelated.ts, 5, 7)) +>Cond2 : Symbol(Cond2, Decl(identicalGenericConditionalsWithInferRelated.ts, 1, 49)) + + x = y; // is err, should be ok +>x : Symbol(x, Decl(identicalGenericConditionalsWithInferRelated.ts, 4, 7)) +>y : Symbol(y, Decl(identicalGenericConditionalsWithInferRelated.ts, 5, 7)) + + y = x; // is err, should be ok +>y : Symbol(y, Decl(identicalGenericConditionalsWithInferRelated.ts, 5, 7)) +>x : Symbol(x, Decl(identicalGenericConditionalsWithInferRelated.ts, 4, 7)) +} + +// repro from https://github.com/microsoft/TypeScript/issues/26627 +export type Constructor = new (...args: any[]) => T +>Constructor : Symbol(Constructor, Decl(identicalGenericConditionalsWithInferRelated.ts, 8, 1)) +>T : Symbol(T, Decl(identicalGenericConditionalsWithInferRelated.ts, 11, 24)) +>args : Symbol(args, Decl(identicalGenericConditionalsWithInferRelated.ts, 11, 34)) +>T : Symbol(T, Decl(identicalGenericConditionalsWithInferRelated.ts, 11, 24)) + +export type MappedResult = +>MappedResult : Symbol(MappedResult, Decl(identicalGenericConditionalsWithInferRelated.ts, 11, 54)) +>T : Symbol(T, Decl(identicalGenericConditionalsWithInferRelated.ts, 12, 25)) + + T extends Boolean ? boolean : +>T : Symbol(T, Decl(identicalGenericConditionalsWithInferRelated.ts, 12, 25)) +>Boolean : Symbol(Boolean, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + + T extends Number ? number : +>T : Symbol(T, Decl(identicalGenericConditionalsWithInferRelated.ts, 12, 25)) +>Number : Symbol(Number, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + + T extends String ? string : +>T : Symbol(T, Decl(identicalGenericConditionalsWithInferRelated.ts, 12, 25)) +>String : Symbol(String, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + + T +>T : Symbol(T, Decl(identicalGenericConditionalsWithInferRelated.ts, 12, 25)) + + +interface X { +>X : Symbol(X, Decl(identicalGenericConditionalsWithInferRelated.ts, 16, 5)) + + decode>(ctor: C): MappedResult ? T : never> +>decode : Symbol(X.decode, Decl(identicalGenericConditionalsWithInferRelated.ts, 19, 13)) +>C : Symbol(C, Decl(identicalGenericConditionalsWithInferRelated.ts, 20, 11)) +>Constructor : Symbol(Constructor, Decl(identicalGenericConditionalsWithInferRelated.ts, 8, 1)) +>ctor : Symbol(ctor, Decl(identicalGenericConditionalsWithInferRelated.ts, 20, 39)) +>C : Symbol(C, Decl(identicalGenericConditionalsWithInferRelated.ts, 20, 11)) +>MappedResult : Symbol(MappedResult, Decl(identicalGenericConditionalsWithInferRelated.ts, 11, 54)) +>C : Symbol(C, Decl(identicalGenericConditionalsWithInferRelated.ts, 20, 11)) +>Constructor : Symbol(Constructor, Decl(identicalGenericConditionalsWithInferRelated.ts, 8, 1)) +>T : Symbol(T, Decl(identicalGenericConditionalsWithInferRelated.ts, 20, 89)) +>T : Symbol(T, Decl(identicalGenericConditionalsWithInferRelated.ts, 20, 89)) +} + +class Y implements X { +>Y : Symbol(Y, Decl(identicalGenericConditionalsWithInferRelated.ts, 21, 1)) +>X : Symbol(X, Decl(identicalGenericConditionalsWithInferRelated.ts, 16, 5)) + + decode>(ctor: C): MappedResult ? T : never> { +>decode : Symbol(Y.decode, Decl(identicalGenericConditionalsWithInferRelated.ts, 23, 22)) +>C : Symbol(C, Decl(identicalGenericConditionalsWithInferRelated.ts, 24, 11)) +>Constructor : Symbol(Constructor, Decl(identicalGenericConditionalsWithInferRelated.ts, 8, 1)) +>ctor : Symbol(ctor, Decl(identicalGenericConditionalsWithInferRelated.ts, 24, 39)) +>C : Symbol(C, Decl(identicalGenericConditionalsWithInferRelated.ts, 24, 11)) +>MappedResult : Symbol(MappedResult, Decl(identicalGenericConditionalsWithInferRelated.ts, 11, 54)) +>C : Symbol(C, Decl(identicalGenericConditionalsWithInferRelated.ts, 24, 11)) +>Constructor : Symbol(Constructor, Decl(identicalGenericConditionalsWithInferRelated.ts, 8, 1)) +>T : Symbol(T, Decl(identicalGenericConditionalsWithInferRelated.ts, 24, 89)) +>T : Symbol(T, Decl(identicalGenericConditionalsWithInferRelated.ts, 24, 89)) + + throw new Error() +>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + } +} + diff --git a/tests/baselines/reference/identicalGenericConditionalsWithInferRelated.types b/tests/baselines/reference/identicalGenericConditionalsWithInferRelated.types new file mode 100644 index 00000000000..c2ec649397d --- /dev/null +++ b/tests/baselines/reference/identicalGenericConditionalsWithInferRelated.types @@ -0,0 +1,65 @@ +=== tests/cases/compiler/identicalGenericConditionalsWithInferRelated.ts === +function f(arg: X) { +>f : (arg: X) => void +>arg : X + + type Cond1 = X extends [infer A] ? A : never; +>Cond1 : X extends [infer A] ? A : never + + type Cond2 = X extends [infer A] ? A : never; +>Cond2 : X extends [infer A] ? A : never + + let x: Cond1 = null as any; +>x : X extends [infer A] ? A : never +>null as any : any +>null : null + + let y: Cond2 = null as any; +>y : X extends [infer A] ? A : never +>null as any : any +>null : null + + x = y; // is err, should be ok +>x = y : X extends [infer A] ? A : never +>x : X extends [infer A] ? A : never +>y : X extends [infer A] ? A : never + + y = x; // is err, should be ok +>y = x : X extends [infer A] ? A : never +>y : X extends [infer A] ? A : never +>x : X extends [infer A] ? A : never +} + +// repro from https://github.com/microsoft/TypeScript/issues/26627 +export type Constructor = new (...args: any[]) => T +>Constructor : Constructor +>args : any[] + +export type MappedResult = +>MappedResult : MappedResult + + T extends Boolean ? boolean : + T extends Number ? number : + T extends String ? string : + T + + +interface X { + decode>(ctor: C): MappedResult ? T : never> +>decode : >(ctor: C) => MappedResult ? T : never> +>ctor : C +} + +class Y implements X { +>Y : Y + + decode>(ctor: C): MappedResult ? T : never> { +>decode : >(ctor: C) => MappedResult ? T : never> +>ctor : C + + throw new Error() +>new Error() : Error +>Error : ErrorConstructor + } +} + diff --git a/tests/cases/compiler/identicalGenericConditionalsWithInferRelated.ts b/tests/cases/compiler/identicalGenericConditionalsWithInferRelated.ts new file mode 100644 index 00000000000..1c7e80780e5 --- /dev/null +++ b/tests/cases/compiler/identicalGenericConditionalsWithInferRelated.ts @@ -0,0 +1,28 @@ +function f(arg: X) { + type Cond1 = X extends [infer A] ? A : never; + type Cond2 = X extends [infer A] ? A : never; + + let x: Cond1 = null as any; + let y: Cond2 = null as any; + x = y; // is err, should be ok + y = x; // is err, should be ok +} + +// repro from https://github.com/microsoft/TypeScript/issues/26627 +export type Constructor = new (...args: any[]) => T +export type MappedResult = + T extends Boolean ? boolean : + T extends Number ? number : + T extends String ? string : + T + + +interface X { + decode>(ctor: C): MappedResult ? T : never> +} + +class Y implements X { + decode>(ctor: C): MappedResult ? T : never> { + throw new Error() + } +} From 6ca9d04b60fd3861ed595e968e266f5ef19b29f2 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Mon, 19 Aug 2019 14:12:53 -0700 Subject: [PATCH 09/10] Constructor functions as classes (#32944) * Initial implementation The original test passes but I haven't run any other tests yet, so I assume the world is now broken. * Append constructor function construct sigs Instead of overwriting them * Grab bag of improvements. 1. Mark @class-tagged functions with Class too. 2. Only gather local type parameters of constructor functions. 3. Remove getJSClassType calls with getDeclaredTypeOfSymbol. 4. Add a couple more failing tests. getDeclaredTypeOfClassOrInterface now needs to understand prototype assignment. That's next, I think. * Prototype assignments work now 1. Binder marks prototype assignments as Class now. 2. Checker merges prototype assignments using the same merge code as for functions and their declarations. No more intersections. Many fewer failing tests now. * Mark prototype-property assignments as Class Even if there are no this-property assignments in them. (Then why are you using a class?). * Simplify getJSClassType, remove calls to its guts It's probably not needed because now it's just a conditional call to getDeclaredTypeOfSymbol, and I think most callers already know whether they have a JS constructor function beforehand. * isJSDocConstructor doesn't need to check prototype anymore Because all the properties are merged during getDeclaredTypeOfSymbol. * outer type parameter lookup follow prototype assignment * this-type and -expression support in ctor funcs Pretty cool! * Fix remaining tests * Fix minor lint * Delete now-unused code * Add class flag to nested class declarations Also remove old TODOs --- src/compiler/binder.ts | 34 +++- src/compiler/checker.ts | 159 ++++++++-------- src/compiler/types.ts | 1 - src/compiler/utilities.ts | 2 +- .../chainedPrototypeAssignment.types | 12 +- ...ExportsObjectAssignPrototypeProperty.types | 6 +- .../classCanExtendConstructorFunction.symbols | 6 + .../classCanExtendConstructorFunction.types | 28 +-- .../reference/constructorFunctions.types | 6 +- .../reference/constructorFunctions2.types | 2 +- .../reference/constructorFunctions3.types | 2 +- .../constructorFunctionsStrict.types | 2 +- .../reference/controlFlowInstanceof.types | 2 +- .../baselines/reference/es5ExportEquals.types | 2 +- .../baselines/reference/es6ExportEquals.types | 2 +- ...nferringClassMembersFromAssignments2.types | 2 +- .../reference/jsEnumCrossFileExport.symbols | 26 +-- ...ototypeNoErrorTruncationNoCrash.errors.txt | 9 +- ...hPrototypeNoErrorTruncationNoCrash.symbols | 10 + ...ithPrototypeNoErrorTruncationNoCrash.types | 64 +++---- .../reference/jsdocFunctionType.types | 4 +- .../jsdocTemplateConstructorFunction.types | 14 +- ...docTemplateConstructorFunction2.errors.txt | 4 +- .../jsdocTemplateConstructorFunction2.symbols | 12 +- .../jsdocTemplateConstructorFunction2.types | 24 ++- .../reference/jsdocTemplateTag4.types | 12 +- .../reference/jsdocTemplateTag5.symbols | 6 + .../reference/jsdocTemplateTag5.types | 12 +- .../jsdocTypeFromChainedAssignment.types | 2 +- .../reference/methodsReturningThis.types | 56 +++--- .../reference/moduleExportAliasImported.types | 2 +- .../reference/multipleDeclarations.types | 2 +- ...rtiesOfGenericConstructorFunctions.symbols | 139 ++++++++++++++ ...pertiesOfGenericConstructorFunctions.types | 173 ++++++++++++++++++ ...PropertyAssignmentMergeAcrossFiles.symbols | 17 ++ ...pePropertyAssignmentMergeAcrossFiles.types | 25 +++ ...naturesUseJSDocForOptionalParameters.types | 2 +- .../thisTypeOfConstructorFunctions.symbols | 118 ++++++++++++ .../thisTypeOfConstructorFunctions.types | 137 ++++++++++++++ .../reference/typeFromJSConstructor.types | 26 +-- .../typeFromPropertyAssignment11.types | 12 +- .../typeFromPropertyAssignment12.types | 10 +- .../typeFromPropertyAssignment13.types | 12 +- .../typeFromPropertyAssignment14.types | 14 +- .../typeFromPropertyAssignment16.types | 14 +- .../typeFromPropertyAssignment20.types | 2 +- .../typeFromPropertyAssignment22.types | 4 +- .../typeFromPropertyAssignment27.types | 8 +- .../typeFromPrototypeAssignment.symbols | 17 ++ .../typeFromPrototypeAssignment.types | 46 ++--- .../typeFromPrototypeAssignment2.symbols | 17 ++ .../typeFromPrototypeAssignment2.types | 46 ++--- .../typeFromPrototypeAssignment3.symbols | 1 + .../typeFromPrototypeAssignment3.types | 8 +- .../reference/umd-augmentation-2.symbols | 4 +- .../reference/umd-augmentation-2.types | 4 +- .../jsdocTemplateConstructorFunction2.ts | 2 + ...propertiesOfGenericConstructorFunctions.ts | 56 ++++++ ...otypePropertyAssignmentMergeAcrossFiles.ts | 10 + .../salsa/thisTypeOfConstructorFunctions.ts | 50 +++++ .../fourslash/jsDocFunctionSignatures8.ts | 2 +- 61 files changed, 1167 insertions(+), 336 deletions(-) create mode 100644 tests/baselines/reference/propertiesOfGenericConstructorFunctions.symbols create mode 100644 tests/baselines/reference/propertiesOfGenericConstructorFunctions.types create mode 100644 tests/baselines/reference/prototypePropertyAssignmentMergeAcrossFiles.symbols create mode 100644 tests/baselines/reference/prototypePropertyAssignmentMergeAcrossFiles.types create mode 100644 tests/baselines/reference/thisTypeOfConstructorFunctions.symbols create mode 100644 tests/baselines/reference/thisTypeOfConstructorFunctions.types create mode 100644 tests/cases/conformance/salsa/propertiesOfGenericConstructorFunctions.ts create mode 100644 tests/cases/conformance/salsa/prototypePropertyAssignmentMergeAcrossFiles.ts create mode 100644 tests/cases/conformance/salsa/thisTypeOfConstructorFunctions.ts diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 6492bb948fa..2b032f456f3 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -227,7 +227,7 @@ namespace ts { symbol.flags |= symbolFlags; node.symbol = symbol; - symbol.declarations = append(symbol.declarations, node); + symbol.declarations = appendIfUnique(symbol.declarations, node); if (symbolFlags & (SymbolFlags.Class | SymbolFlags.Enum | SymbolFlags.Module | SymbolFlags.Variable) && !symbol.exports) { symbol.exports = createSymbolTable(); @@ -737,6 +737,9 @@ namespace ts { case SyntaxKind.JSDocEnumTag: bindJSDocTypeAlias(node as JSDocTypedefTag | JSDocCallbackTag | JSDocEnumTag); break; + case SyntaxKind.JSDocClassTag: + bindJSDocClassTag(node as JSDocClassTag); + break; // In source files and blocks, bind functions first to match hoisting that occurs at runtime case SyntaxKind.SourceFile: { bindEachFunctionsFirst((node as SourceFile).statements); @@ -1446,6 +1449,14 @@ namespace ts { } } + function bindJSDocClassTag(node: JSDocClassTag) { + bindEachChild(node); + const host = getHostSignatureFromJSDoc(node); + if (host && host.kind !== SyntaxKind.MethodDeclaration) { + addDeclarationToSymbol(host.symbol, host, SymbolFlags.Class); + } + } + function bindCallExpressionFlow(node: CallExpression) { // If the target of the call expression is a function expression or arrow function we have // an immediately invoked function expression (IIFE). Initialize the flowNode property to @@ -1813,7 +1824,8 @@ namespace ts { // typedef anchored to an A.B.C assignment - we need to bind into B's namespace under name C const isTopLevel = isTopLevelNamespaceAssignment(declName.parent); if (isTopLevel) { - bindPotentiallyMissingNamespaces(file.symbol, declName.parent, isTopLevel, !!findAncestor(declName, d => isPropertyAccessExpression(d) && d.name.escapedText === "prototype")); + bindPotentiallyMissingNamespaces(file.symbol, declName.parent, isTopLevel, + !!findAncestor(declName, d => isPropertyAccessExpression(d) && d.name.escapedText === "prototype"), /*containerIsClass*/ false); const oldContainer = container; container = isPropertyAccessExpression(declName.parent.expression) ? declName.parent.expression.name : declName.parent.expression; declareModuleMember(typeAlias, SymbolFlags.TypeAlias, SymbolFlags.TypeAliasExcludes); @@ -2510,6 +2522,7 @@ namespace ts { constructorSymbol.members = constructorSymbol.members || createSymbolTable(); // It's acceptable for multiple 'this' assignments of the same identifier to occur declareSymbol(constructorSymbol.members, constructorSymbol, node, SymbolFlags.Property, SymbolFlags.PropertyExcludes & ~SymbolFlags.Property); + addDeclarationToSymbol(constructorSymbol, constructorSymbol.valueDeclaration, SymbolFlags.Class); } break; @@ -2558,7 +2571,7 @@ namespace ts { node.left.parent = node; node.right.parent = node; const lhs = node.left as PropertyAccessEntityNameExpression; - bindPropertyAssignment(lhs.expression, lhs, /*isPrototypeProperty*/ false); + bindPropertyAssignment(lhs.expression, lhs, /*isPrototypeProperty*/ false, /*containerIsClass*/ true); } function bindObjectDefinePrototypeProperty(node: BindableObjectDefinePropertyCall) { @@ -2581,13 +2594,13 @@ namespace ts { constructorFunction.parent = classPrototype; classPrototype.parent = lhs; - bindPropertyAssignment(constructorFunction, lhs, /*isPrototypeProperty*/ true); + bindPropertyAssignment(constructorFunction, lhs, /*isPrototypeProperty*/ true, /*containerIsClass*/ true); } function bindObjectDefinePropertyAssignment(node: BindableObjectDefinePropertyCall) { let namespaceSymbol = lookupSymbolForPropertyAccess(node.arguments[0]); const isToplevel = node.parent.parent.kind === SyntaxKind.SourceFile; - namespaceSymbol = bindPotentiallyMissingNamespaces(namespaceSymbol, node.arguments[0], isToplevel, /*isPrototypeProperty*/ false); + namespaceSymbol = bindPotentiallyMissingNamespaces(namespaceSymbol, node.arguments[0], isToplevel, /*isPrototypeProperty*/ false, /*containerIsClass*/ false); bindPotentiallyNewExpandoMemberToNamespace(node, namespaceSymbol, /*isPrototypeProperty*/ false); } @@ -2618,10 +2631,10 @@ namespace ts { */ function bindStaticPropertyAssignment(node: PropertyAccessEntityNameExpression) { node.expression.parent = node; - bindPropertyAssignment(node.expression, node, /*isPrototypeProperty*/ false); + bindPropertyAssignment(node.expression, node, /*isPrototypeProperty*/ false, /*containerIsClass*/ false); } - function bindPotentiallyMissingNamespaces(namespaceSymbol: Symbol | undefined, entityName: EntityNameExpression, isToplevel: boolean, isPrototypeProperty: boolean) { + function bindPotentiallyMissingNamespaces(namespaceSymbol: Symbol | undefined, entityName: EntityNameExpression, isToplevel: boolean, isPrototypeProperty: boolean, containerIsClass: boolean) { if (isToplevel && !isPrototypeProperty) { // make symbols or add declarations for intermediate containers const flags = SymbolFlags.Module | SymbolFlags.Assignment; @@ -2638,6 +2651,9 @@ namespace ts { } }); } + if (containerIsClass && namespaceSymbol) { + addDeclarationToSymbol(namespaceSymbol, namespaceSymbol.valueDeclaration, SymbolFlags.Class); + } return namespaceSymbol; } @@ -2663,10 +2679,10 @@ namespace ts { : propertyAccess.parent.parent.kind === SyntaxKind.SourceFile; } - function bindPropertyAssignment(name: EntityNameExpression, propertyAccess: PropertyAccessEntityNameExpression, isPrototypeProperty: boolean) { + function bindPropertyAssignment(name: EntityNameExpression, propertyAccess: PropertyAccessEntityNameExpression, isPrototypeProperty: boolean, containerIsClass: boolean) { let namespaceSymbol = lookupSymbolForPropertyAccess(name); const isToplevel = isTopLevelNamespaceAssignment(propertyAccess); - namespaceSymbol = bindPotentiallyMissingNamespaces(namespaceSymbol, propertyAccess.expression, isToplevel, isPrototypeProperty); + namespaceSymbol = bindPotentiallyMissingNamespaces(namespaceSymbol, propertyAccess.expression, isToplevel, isPrototypeProperty, containerIsClass); bindPotentiallyNewExpandoMemberToNamespace(propertyAccess, namespaceSymbol, isPrototypeProperty); } diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 84e3ed842cf..981aa78fc84 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2041,12 +2041,16 @@ namespace ts { function checkResolvedBlockScopedVariable(result: Symbol, errorLocation: Node): void { Debug.assert(!!(result.flags & SymbolFlags.BlockScopedVariable || result.flags & SymbolFlags.Class || result.flags & SymbolFlags.Enum)); + if (result.flags & (SymbolFlags.Function | SymbolFlags.FunctionScopedVariable | SymbolFlags.Assignment) && result.flags & SymbolFlags.Class) { + // constructor functions aren't block scoped + return; + } // Block-scoped variables cannot be used before their definition const declaration = find( result.declarations, d => isBlockOrCatchScoped(d) || isClassLike(d) || (d.kind === SyntaxKind.EnumDeclaration)); - if (declaration === undefined) return Debug.fail("Declaration to checkResolvedBlockScopedVariable is undefined"); + if (declaration === undefined) return Debug.fail("checkResolvedBlockScopedVariable could not find block-scoped declaration"); if (!(declaration.flags & NodeFlags.Ambient) && !isBlockScopedNameDeclaredBeforeUse(declaration, errorLocation)) { let diagnosticMessage; @@ -3811,7 +3815,7 @@ namespace ts { id = (isConstructorObject ? "+" : "") + getSymbolId(symbol); if (isJSConstructor(symbol.valueDeclaration)) { // Instance and static types share the same symbol; only add 'typeof' for the static side. - const isInstanceType = type === getInferredClassType(symbol) ? SymbolFlags.Type : SymbolFlags.Value; + const isInstanceType = type === getDeclaredTypeOfClassOrInterface(symbol) ? SymbolFlags.Type : SymbolFlags.Value; return symbolToTypeNode(symbol, context, isInstanceType); } // Always use 'typeof T' for type of class, enum, and module objects @@ -5974,19 +5978,10 @@ namespace ts { if (!links.type) { const jsDeclaration = getDeclarationOfExpando(symbol.valueDeclaration); if (jsDeclaration) { - const jsSymbol = getSymbolOfNode(jsDeclaration); - if (jsSymbol && (hasEntries(jsSymbol.exports) || hasEntries(jsSymbol.members))) { - symbol = cloneSymbol(symbol); + const merged = mergeJSSymbols(symbol, getSymbolOfNode(jsDeclaration)); + if (merged) { // note:we overwrite links because we just cloned the symbol - links = symbol as TransientSymbol; - if (hasEntries(jsSymbol.exports)) { - symbol.exports = symbol.exports || createSymbolTable(); - mergeSymbolTable(symbol.exports, jsSymbol.exports); - } - if (hasEntries(jsSymbol.members)) { - symbol.members = symbol.members || createSymbolTable(); - mergeSymbolTable(symbol.members, jsSymbol.members); - } + symbol = links = merged; } } originalLinks.type = links.type = getTypeOfFuncClassEnumModuleWorker(symbol); @@ -6161,6 +6156,16 @@ namespace ts { function getOuterTypeParameters(node: Node, includeThisTypes?: boolean): TypeParameter[] | undefined { while (true) { node = node.parent; // TODO: GH#18217 Use SourceFile kind check instead + if (node && isBinaryExpression(node)) { + // prototype assignments get the outer type parameters of their constructor function + const assignmentKind = getAssignmentDeclarationKind(node); + if (assignmentKind === AssignmentDeclarationKind.Prototype || assignmentKind === AssignmentDeclarationKind.PrototypeProperty) { + const symbol = getSymbolOfNode(node.left); + if (symbol && symbol.parent && !findAncestor(symbol.parent.valueDeclaration, d => node === d)) { + node = symbol.parent.valueDeclaration; + } + } + } if (!node) { return undefined; } @@ -6194,7 +6199,7 @@ namespace ts { } const outerAndOwnTypeParameters = appendTypeParameters(outerTypeParameters, getEffectiveTypeParameterDeclarations(node)); const thisType = includeThisTypes && - (node.kind === SyntaxKind.ClassDeclaration || node.kind === SyntaxKind.ClassExpression || node.kind === SyntaxKind.InterfaceDeclaration) && + (node.kind === SyntaxKind.ClassDeclaration || node.kind === SyntaxKind.ClassExpression || node.kind === SyntaxKind.InterfaceDeclaration || isJSConstructor(node)) && getDeclaredTypeOfClassOrInterface(getSymbolOfNode(node as ClassLikeDeclaration | InterfaceDeclaration)).thisType; return thisType ? append(outerAndOwnTypeParameters, thisType) : outerAndOwnTypeParameters; } @@ -6215,6 +6220,7 @@ namespace ts { if (node.kind === SyntaxKind.InterfaceDeclaration || node.kind === SyntaxKind.ClassDeclaration || node.kind === SyntaxKind.ClassExpression || + isJSConstructor(node) || isTypeAlias(node)) { const declaration = node; result = appendTypeParameters(result, getEffectiveTypeParameterDeclarations(declaration)); @@ -6248,7 +6254,7 @@ namespace ts { const constraint = getBaseConstraintOfType(type); return !!constraint && isValidBaseType(constraint) && isMixinConstructorType(constraint); } - return isJSConstructorType(type); + return false; } function getBaseTypeNodeOfClass(type: InterfaceType): ExpressionWithTypeArguments | undefined { @@ -6350,9 +6356,7 @@ namespace ts { const baseTypeNode = getBaseTypeNodeOfClass(type)!; const typeArgs = typeArgumentsFromTypeReferenceNode(baseTypeNode); let baseType: Type; - const originalBaseType = isJSConstructorType(baseConstructorType) ? baseConstructorType : - baseConstructorType.symbol ? getDeclaredTypeOfSymbol(baseConstructorType.symbol) : - undefined; + const originalBaseType = baseConstructorType.symbol ? getDeclaredTypeOfSymbol(baseConstructorType.symbol) : undefined; if (baseConstructorType.symbol && baseConstructorType.symbol.flags & SymbolFlags.Class && areAllOuterTypeParametersApplied(originalBaseType!)) { // When base constructor type is a class with no captured type arguments we know that the constructors all have the same type parameters as the @@ -6363,9 +6367,6 @@ namespace ts { else if (baseConstructorType.flags & TypeFlags.Any) { baseType = baseConstructorType; } - else if (isJSConstructorType(baseConstructorType)) { - baseType = !baseTypeNode.typeArguments && getJSClassType(baseConstructorType.symbol) || anyType; - } else { // The class derives from a "class-like" constructor function, check that we have at least one construct signature // with a matching number of type parameters and use the return type of the first instantiated signature. Elsewhere @@ -6478,10 +6479,17 @@ namespace ts { } function getDeclaredTypeOfClassOrInterface(symbol: Symbol): InterfaceType { - const links = getSymbolLinks(symbol); + let links = getSymbolLinks(symbol); + const originalLinks = links; if (!links.declaredType) { const kind = symbol.flags & SymbolFlags.Class ? ObjectFlags.Class : ObjectFlags.Interface; - const type = links.declaredType = createObjectType(kind, symbol); + const merged = mergeJSSymbols(symbol, getAssignedClassSymbol(symbol.valueDeclaration)); + if (merged) { + // note:we overwrite links because we just cloned the symbol + symbol = links = merged; + } + + const type = originalLinks.declaredType = links.declaredType = createObjectType(kind, symbol); const outerTypeParameters = getOuterTypeParametersOfClassOrInterface(symbol); const localTypeParameters = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol); // A class or interface is generic if it has type parameters or a "this" type. We always give classes a "this" type @@ -7452,7 +7460,7 @@ namespace ts { * Converts an AnonymousType to a ResolvedType. */ function resolveAnonymousTypeMembers(type: AnonymousType) { - const symbol = type.symbol; + const symbol = getMergedSymbol(type.symbol); if (type.target) { setStructuredTypeMembers(type, emptySymbols, emptyArray, emptyArray, undefined, undefined); const members = createInstantiatedSymbolTable(getPropertiesOfObjectType(type.target), type.mapper!, /*mappingThisOnly*/ false); @@ -7508,12 +7516,18 @@ namespace ts { // will never be observed because a qualified name can't reference signatures. if (symbol.flags & (SymbolFlags.Function | SymbolFlags.Method)) { type.callSignatures = getSignaturesOfSymbol(symbol); - type.constructSignatures = filter(type.callSignatures, sig => isJSConstructor(sig.declaration)); } // And likewise for construct signatures for classes if (symbol.flags & SymbolFlags.Class) { const classType = getDeclaredTypeOfClassOrInterface(symbol); - let constructSignatures = getSignaturesOfSymbol(symbol.members!.get(InternalSymbolName.Constructor)); + let constructSignatures = symbol.members ? getSignaturesOfSymbol(symbol.members.get(InternalSymbolName.Constructor)) : emptyArray; + if (symbol.flags & SymbolFlags.Function) { + constructSignatures = addRange(constructSignatures.slice(), mapDefined( + type.callSignatures, + sig => isJSConstructor(sig.declaration) ? + createSignature(sig.declaration, sig.typeParameters, sig.thisParameter, sig.parameters, classType, /*resolvedTypePredicate*/ undefined, sig.minArgumentCount, sig.hasRestParameter, sig.hasLiteralTypes) : + undefined)); + } if (!constructSignatures.length) { constructSignatures = getDefaultConstructSignatures(classType); } @@ -8748,7 +8762,6 @@ namespace ts { let type = signature.target ? instantiateType(getReturnTypeOfSignature(signature.target), signature.mapper!) : signature.unionSignatures ? getUnionType(map(signature.unionSignatures, getReturnTypeOfSignature), UnionReduction.Subtype) : getReturnTypeFromAnnotation(signature.declaration!) || - isJSConstructor(signature.declaration) && getJSClassType(getSymbolOfNode(signature.declaration!)) || (nodeIsMissing((signature.declaration).body) ? anyType : getReturnTypeFromBody(signature.declaration)); if (!popTypeResolution()) { if (signature.declaration) { @@ -11096,10 +11109,25 @@ namespace ts { const parent = container && container.parent; if (parent && (isClassLike(parent) || parent.kind === SyntaxKind.InterfaceDeclaration)) { if (!hasModifier(container, ModifierFlags.Static) && - (container.kind !== SyntaxKind.Constructor || isNodeDescendantOf(node, (container).body!))) { + (!isConstructorDeclaration(container) || isNodeDescendantOf(node, container.body))) { return getDeclaredTypeOfClassOrInterface(getSymbolOfNode(parent as ClassLikeDeclaration | InterfaceDeclaration)).thisType!; } } + + // inside x.prototype = { ... } + if (parent && isObjectLiteralExpression(parent) && isBinaryExpression(parent.parent) && getAssignmentDeclarationKind(parent.parent) === AssignmentDeclarationKind.Prototype) { + return getDeclaredTypeOfClassOrInterface(getSymbolOfNode(parent.parent.left)!.parent!).thisType!; + } + // /** @return {this} */ + // x.prototype.m = function() { ... } + const host = node.flags & NodeFlags.JSDoc ? getHostSignatureFromJSDoc(node) : undefined; + if (host && isFunctionExpression(host) && isBinaryExpression(host.parent) && getAssignmentDeclarationKind(host.parent) === AssignmentDeclarationKind.PrototypeProperty) { + return getDeclaredTypeOfClassOrInterface(getSymbolOfNode(host.parent.left)!.parent!).thisType!; + } + // inside constructor function C() { ... } + if (isJSConstructor(container) && isNodeDescendantOf(node, container.body)) { + return getDeclaredTypeOfClassOrInterface(getSymbolOfNode(container)).thisType!; + } error(node, Diagnostics.A_this_type_is_available_only_in_a_non_static_member_of_a_class_or_interface); return errorType; } @@ -12391,15 +12419,17 @@ namespace ts { } if (!ignoreReturnTypes) { - // If a signature reolution is already in-flight, skip issuing a circularity error + // If a signature resolution is already in-flight, skip issuing a circularity error // here and just use the `any` type directly - const targetReturnType = isResolvingReturnTypeOfSignature(target) ? anyType : (target.declaration && isJSConstructor(target.declaration)) ? - getJSClassType(target.declaration.symbol)! : getReturnTypeOfSignature(target); + const targetReturnType = isResolvingReturnTypeOfSignature(target) ? anyType + : target.declaration && isJSConstructor(target.declaration) ? getDeclaredTypeOfClassOrInterface(target.declaration.symbol) + : getReturnTypeOfSignature(target); if (targetReturnType === voidType) { return result; } - const sourceReturnType = isResolvingReturnTypeOfSignature(source) ? anyType : (source.declaration && isJSConstructor(source.declaration)) ? - getJSClassType(source.declaration.symbol)! : getReturnTypeOfSignature(source); + const sourceReturnType = isResolvingReturnTypeOfSignature(source) ? anyType + : source.declaration && isJSConstructor(source.declaration) ? getDeclaredTypeOfClassOrInterface(source.declaration.symbol) + : getReturnTypeOfSignature(source); // The following block preserves behavior forbidding boolean returning functions from being assignable to type guard returning functions const targetTypePredicate = getTypePredicateOfSignature(target); @@ -18289,10 +18319,8 @@ namespace ts { if (isInJS && className) { const classSymbol = checkExpression(className).symbol; if (classSymbol && classSymbol.members && (classSymbol.flags & SymbolFlags.Function)) { - const classType = getJSClassType(classSymbol); - if (classType) { - return getFlowTypeOfReference(node, classType); - } + const classType = (getDeclaredTypeOfSymbol(classSymbol) as InterfaceType).thisType!; + return getFlowTypeOfReference(node, classType); } } // Check if it's a constructor definition, can be either a variable decl or function decl @@ -18302,10 +18330,8 @@ namespace ts { else if (isInJS && (container.kind === SyntaxKind.FunctionExpression || container.kind === SyntaxKind.FunctionDeclaration) && getJSDocClassTag(container)) { - const classType = getJSClassType(getMergedSymbol(container.symbol)); - if (classType) { - return getFlowTypeOfReference(node, classType); - } + const classType = (getDeclaredTypeOfSymbol(getMergedSymbol(container.symbol)) as InterfaceType).thisType!; + return getFlowTypeOfReference(node, classType); } const thisType = getThisTypeOfDeclaration(container) || getContextualThisParameterType(container); @@ -18316,7 +18342,7 @@ namespace ts { if (isClassLike(container.parent)) { const symbol = getSymbolOfNode(container.parent); - const type = hasModifier(container, ModifierFlags.Static) ? getTypeOfSymbol(symbol) : (getDeclaredTypeOfSymbol(symbol)).thisType!; + const type = hasModifier(container, ModifierFlags.Static) ? getTypeOfSymbol(symbol) : (getDeclaredTypeOfSymbol(symbol) as InterfaceType).thisType!; return getFlowTypeOfReference(node, type); } @@ -22836,7 +22862,7 @@ namespace ts { * Indicates whether a declaration can be treated as a constructor in a JavaScript * file. */ - function isJSConstructor(node: Declaration | undefined): boolean { + function isJSConstructor(node: Node | undefined): node is FunctionDeclaration | FunctionExpression { if (!node || !isInJSFile(node)) { return false; } @@ -22849,39 +22875,35 @@ namespace ts { // If the symbol of the node has members, treat it like a constructor. const symbol = getSymbolOfNode(func); - return !!symbol && (symbol.members !== undefined || symbol.exports !== undefined && symbol.exports.get("prototype" as __String) !== undefined); + return !!symbol && symbol.members !== undefined; } return false; } - function isJSConstructorType(type: Type) { - if (type.flags & TypeFlags.Object) { - const resolved = resolveStructuredTypeMembers(type); - return resolved.callSignatures.length === 1 && isJSConstructor(resolved.callSignatures[0].declaration); + function mergeJSSymbols(target: Symbol, source: Symbol | undefined) { + if (source && (hasEntries(source.exports) || hasEntries(source.members))) { + target = cloneSymbol(target); + if (hasEntries(source.exports)) { + target.exports = target.exports || createSymbolTable(); + mergeSymbolTable(target.exports, source.exports); + } + if (hasEntries(source.members)) { + target.members = target.members || createSymbolTable(); + mergeSymbolTable(target.members, source.members); + } + target.flags |= source.flags & SymbolFlags.Class; + return target as TransientSymbol; } - return false; } - function getJSClassType(symbol: Symbol): Type | undefined { - let inferred: Type | undefined; - if (isJSConstructor(symbol.valueDeclaration)) { - inferred = getInferredClassType(symbol); - } - const assigned = getAssignedClassType(symbol); - return assigned && inferred ? - getIntersectionType([inferred, assigned]) : - assigned || inferred; - } - - function getAssignedClassType(symbol: Symbol): Type | undefined { - const decl = symbol.valueDeclaration; + function getAssignedClassSymbol(decl: Declaration): Symbol | undefined { const assignmentSymbol = decl && decl.parent && (isFunctionDeclaration(decl) && getSymbolOfNode(decl) || isBinaryExpression(decl.parent) && getSymbolOfNode(decl.parent.left) || isVariableDeclaration(decl.parent) && getSymbolOfNode(decl.parent)); const prototype = assignmentSymbol && assignmentSymbol.exports && assignmentSymbol.exports.get("prototype" as __String); const init = prototype && prototype.valueDeclaration && getAssignedJSPrototype(prototype.valueDeclaration); - return init ? getWidenedType(checkExpressionCached(init)) : undefined; + return init ? getSymbolOfNode(init) : undefined; } function getAssignedJSPrototype(node: Node) { @@ -22898,15 +22920,6 @@ namespace ts { } } - - function getInferredClassType(symbol: Symbol) { - const links = getSymbolLinks(symbol); - if (!links.inferredClassType) { - links.inferredClassType = createAnonymousType(symbol, getMembersOfSymbol(symbol) || emptySymbols, emptyArray, emptyArray, /*stringIndexType*/ undefined, /*numberIndexType*/ undefined); - } - return links.inferredClassType; - } - /** * Syntactically and semantically checks a call or new expression. * @param node The call/new expression to be checked. diff --git a/src/compiler/types.ts b/src/compiler/types.ts index b3565e7797d..5e6f36346e3 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -3778,7 +3778,6 @@ namespace ts { resolvedJSDocType?: Type; // Resolved type of a JSDoc type reference typeParameters?: TypeParameter[]; // Type parameters of type alias (undefined if non-generic) outerTypeParameters?: TypeParameter[]; // Outer type parameters of anonymous object type - inferredClassType?: Type; // Type of an inferred ES5 class instantiations?: Map; // Instantiations of generic type alias (undefined if non-generic) mapper?: TypeMapper; // Type mapper for instantiation alias referenced?: boolean; // True if alias symbol has been referenced as a value diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 58936916842..8de82631fb5 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -2507,7 +2507,7 @@ namespace ts { return node && node.kind === SyntaxKind.DeleteExpression; } - export function isNodeDescendantOf(node: Node, ancestor: Node): boolean { + export function isNodeDescendantOf(node: Node, ancestor: Node | undefined): boolean { while (node) { if (node === ancestor) return true; node = node.parent; diff --git a/tests/baselines/reference/chainedPrototypeAssignment.types b/tests/baselines/reference/chainedPrototypeAssignment.types index 08ddcbf2baf..6e877361ae6 100644 --- a/tests/baselines/reference/chainedPrototypeAssignment.types +++ b/tests/baselines/reference/chainedPrototypeAssignment.types @@ -7,15 +7,15 @@ var mod = require('./mod'); >'./mod' : "./mod" var a = new mod.A() ->a : A & { m(n: number): number; } ->new mod.A() : A & { m(n: number): number; } +>a : A +>new mod.A() : A >mod.A : typeof A >mod : typeof import("tests/cases/conformance/salsa/mod") >A : typeof A var b = new mod.B() ->b : B & { m(n: number): number; } ->new mod.B() : B & { m(n: number): number; } +>b : B +>new mod.B() : B >mod.B : typeof B >mod : typeof import("tests/cases/conformance/salsa/mod") >B : typeof B @@ -23,14 +23,14 @@ var b = new mod.B() a.m('nope') >a.m('nope') : number >a.m : (n: number) => number ->a : A & { m(n: number): number; } +>a : A >m : (n: number) => number >'nope' : "nope" b.m('not really') >b.m('not really') : number >b.m : (n: number) => number ->b : B & { m(n: number): number; } +>b : B >m : (n: number) => number >'not really' : "not really" diff --git a/tests/baselines/reference/checkExportsObjectAssignPrototypeProperty.types b/tests/baselines/reference/checkExportsObjectAssignPrototypeProperty.types index 662c578701f..66a814e92f2 100644 --- a/tests/baselines/reference/checkExportsObjectAssignPrototypeProperty.types +++ b/tests/baselines/reference/checkExportsObjectAssignPrototypeProperty.types @@ -106,7 +106,7 @@ function Person(name) { this.name = name; >this.name = name : string >this.name : string ->this : Person +>this : this >name : string >name : string } @@ -123,7 +123,7 @@ Person.prototype.describe = function () { >"Person called " + this.name : string >"Person called " : "Person called " >this.name : string ->this : Person +>this : this >name : string }; @@ -204,7 +204,7 @@ Object.defineProperty(Person.prototype, "setonlyAccessor", { this.rwAccessors = Number(str) >this.rwAccessors = Number(str) : number >this.rwAccessors : number ->this : Person +>this : this >rwAccessors : number >Number(str) : number >Number : NumberConstructor diff --git a/tests/baselines/reference/classCanExtendConstructorFunction.symbols b/tests/baselines/reference/classCanExtendConstructorFunction.symbols index bd935a8a5b8..c1c8be92725 100644 --- a/tests/baselines/reference/classCanExtendConstructorFunction.symbols +++ b/tests/baselines/reference/classCanExtendConstructorFunction.symbols @@ -205,7 +205,9 @@ class Chowder extends Soup { >log : Symbol(Chowder.log, Decl(generic.js, 8, 28)) return this.flavour +>this.flavour : Symbol(Soup.flavour, Decl(generic.js, 4, 24)) >this : Symbol(Chowder, Decl(generic.js, 6, 1)) +>flavour : Symbol(Soup.flavour, Decl(generic.js, 4, 24)) } } @@ -224,7 +226,11 @@ var chowder = new Chowder({ claim: "ignorant" }); >claim : Symbol(claim, Decl(generic.js, 16, 27)) chowder.flavour.claim +>chowder.flavour.claim : Symbol(claim, Decl(generic.js, 7, 20)) +>chowder.flavour : Symbol(Soup.flavour, Decl(generic.js, 4, 24)) >chowder : Symbol(chowder, Decl(generic.js, 16, 3)) +>flavour : Symbol(Soup.flavour, Decl(generic.js, 4, 24)) +>claim : Symbol(claim, Decl(generic.js, 7, 20)) var errorNoArgs = new Chowder(); >errorNoArgs : Symbol(errorNoArgs, Decl(generic.js, 18, 3)) diff --git a/tests/baselines/reference/classCanExtendConstructorFunction.types b/tests/baselines/reference/classCanExtendConstructorFunction.types index c9ac9c76ebf..d2de5468efd 100644 --- a/tests/baselines/reference/classCanExtendConstructorFunction.types +++ b/tests/baselines/reference/classCanExtendConstructorFunction.types @@ -10,7 +10,7 @@ function Wagon(numberOxen) { this.numberOxen = numberOxen >this.numberOxen = numberOxen : number >this.numberOxen : number ->this : Wagon +>this : this >numberOxen : number >numberOxen : number } @@ -72,11 +72,11 @@ Wagon.prototype.speed = function () { return this.numberOxen / this.weight() >this.numberOxen / this.weight() : number >this.numberOxen : number ->this : Wagon +>this : this >numberOxen : number >this.weight() : number >this.weight : (supplies?: any[]) => number ->this : Wagon +>this : this >weight : (supplies?: any[]) => number } // ok @@ -245,27 +245,27 @@ function Soup(flavour) { /** @extends {Soup<{ claim: "ignorant" | "malicious" }>} */ class Chowder extends Soup { >Chowder : Chowder ->Soup : typeof Soup +>Soup : Soup<{ claim: "ignorant" | "malicious"; }> log() { ->log : () => any +>log : () => { claim: "ignorant" | "malicious"; } return this.flavour ->this.flavour : any +>this.flavour : { claim: "ignorant" | "malicious"; } >this : this ->flavour : any +>flavour : { claim: "ignorant" | "malicious"; } } } var soup = new Soup(1); ->soup : typeof Soup ->new Soup(1) : typeof Soup +>soup : Soup +>new Soup(1) : Soup >Soup : typeof Soup >1 : 1 soup.flavour >soup.flavour : number ->soup : typeof Soup +>soup : Soup >flavour : number var chowder = new Chowder({ claim: "ignorant" }); @@ -277,11 +277,11 @@ var chowder = new Chowder({ claim: "ignorant" }); >"ignorant" : "ignorant" chowder.flavour.claim ->chowder.flavour.claim : any ->chowder.flavour : any +>chowder.flavour.claim : "ignorant" | "malicious" +>chowder.flavour : { claim: "ignorant" | "malicious"; } >chowder : Chowder ->flavour : any ->claim : any +>flavour : { claim: "ignorant" | "malicious"; } +>claim : "ignorant" | "malicious" var errorNoArgs = new Chowder(); >errorNoArgs : any diff --git a/tests/baselines/reference/constructorFunctions.types b/tests/baselines/reference/constructorFunctions.types index d5bd4425435..05f3998a09c 100644 --- a/tests/baselines/reference/constructorFunctions.types +++ b/tests/baselines/reference/constructorFunctions.types @@ -69,7 +69,7 @@ function C3() { >!(this instanceof C3) : boolean >(this instanceof C3) : boolean >this instanceof C3 : boolean ->this : C3 +>this : this >C3 : typeof C3 >new C3() : C3 >C3 : typeof C3 @@ -95,7 +95,7 @@ var C4 = function () { >!(this instanceof C4) : boolean >(this instanceof C4) : boolean >this instanceof C4 : boolean ->this : C4 +>this : this >C4 : typeof C4 >new C4() : C4 >C4 : typeof C4 @@ -144,7 +144,7 @@ function C6() { this.functions = [x => x, x => x + 1, x => x - 1] >this.functions = [x => x, x => x + 1, x => x - 1] : ((x: any) => any)[] >this.functions : ((x: any) => any)[] ->this : C6 +>this : this >functions : ((x: any) => any)[] >[x => x, x => x + 1, x => x - 1] : ((x: any) => any)[] >x => x : (x: any) => any diff --git a/tests/baselines/reference/constructorFunctions2.types b/tests/baselines/reference/constructorFunctions2.types index b35b5ce2f2f..208a343375d 100644 --- a/tests/baselines/reference/constructorFunctions2.types +++ b/tests/baselines/reference/constructorFunctions2.types @@ -40,7 +40,7 @@ B.prototype.m = function() { this.x = 2; } >function() { this.x = 2; } : () => void >this.x = 2 : 2 >this.x : number ->this : B +>this : this >x : number >2 : 2 diff --git a/tests/baselines/reference/constructorFunctions3.types b/tests/baselines/reference/constructorFunctions3.types index 134f8c118e7..d15681c1c86 100644 --- a/tests/baselines/reference/constructorFunctions3.types +++ b/tests/baselines/reference/constructorFunctions3.types @@ -83,7 +83,7 @@ A.prototype.z = function f(n) { >n + this.x : number >n : number >this.x : number ->this : A +>this : this >x : number } /** @param {number} m */ diff --git a/tests/baselines/reference/constructorFunctionsStrict.types b/tests/baselines/reference/constructorFunctionsStrict.types index d2dcffd81d6..daeffbdd7ff 100644 --- a/tests/baselines/reference/constructorFunctionsStrict.types +++ b/tests/baselines/reference/constructorFunctionsStrict.types @@ -23,7 +23,7 @@ C.prototype.m = function() { this.y = 12 >this.y = 12 : 12 >this.y : number | undefined ->this : C +>this : this >y : number | undefined >12 : 12 } diff --git a/tests/baselines/reference/controlFlowInstanceof.types b/tests/baselines/reference/controlFlowInstanceof.types index 9aa38025a1c..7f10128c08e 100644 --- a/tests/baselines/reference/controlFlowInstanceof.types +++ b/tests/baselines/reference/controlFlowInstanceof.types @@ -269,7 +269,7 @@ function AtTop(val) { this.val = val } >val : any >this.val = val : any >this.val : any ->this : AtTop +>this : this >val : any >val : any diff --git a/tests/baselines/reference/es5ExportEquals.types b/tests/baselines/reference/es5ExportEquals.types index 6c9e8930537..f6273376a7c 100644 --- a/tests/baselines/reference/es5ExportEquals.types +++ b/tests/baselines/reference/es5ExportEquals.types @@ -3,5 +3,5 @@ export function f() { } >f : typeof f export = f; ->f : () => void +>f : { (): void; f: typeof import("tests/cases/compiler/es5ExportEquals").f; } diff --git a/tests/baselines/reference/es6ExportEquals.types b/tests/baselines/reference/es6ExportEquals.types index 3ba761dc8e5..eb8e59c31be 100644 --- a/tests/baselines/reference/es6ExportEquals.types +++ b/tests/baselines/reference/es6ExportEquals.types @@ -3,5 +3,5 @@ export function f() { } >f : typeof f export = f; ->f : () => void +>f : { (): void; f: typeof import("tests/cases/compiler/es6ExportEquals").f; } diff --git a/tests/baselines/reference/inferringClassMembersFromAssignments2.types b/tests/baselines/reference/inferringClassMembersFromAssignments2.types index 004cb9e1f76..39c00bc9181 100644 --- a/tests/baselines/reference/inferringClassMembersFromAssignments2.types +++ b/tests/baselines/reference/inferringClassMembersFromAssignments2.types @@ -11,7 +11,7 @@ OOOrder.prototype.m = function () { this.p = 1 >this.p = 1 : 1 >this.p : number ->this : OOOrder +>this : this >p : number >1 : 1 } diff --git a/tests/baselines/reference/jsEnumCrossFileExport.symbols b/tests/baselines/reference/jsEnumCrossFileExport.symbols index 60d27769652..0ddc0d5b551 100644 --- a/tests/baselines/reference/jsEnumCrossFileExport.symbols +++ b/tests/baselines/reference/jsEnumCrossFileExport.symbols @@ -1,18 +1,18 @@ === tests/cases/compiler/enumDef.js === var Host = {}; ->Host : Symbol(Host, Decl(enumDef.js, 0, 3), Decl(enumDef.js, 0, 14), Decl(enumDef.js, 1, 22), Decl(enumDef.js, 8, 2), Decl(enumDef.js, 1, 22) ... and 2 more) +>Host : Symbol(Host, Decl(enumDef.js, 0, 3), Decl(enumDef.js, 0, 14), Decl(enumDef.js, 1, 22), Decl(enumDef.js, 8, 2), Decl(enumDef.js, 10, 21)) Host.UserMetrics = {}; ->Host.UserMetrics : Symbol(Host.UserMetrics, Decl(enumDef.js, 0, 14), Decl(enumDef.js, 3, 5), Decl(enumDef.js, 15, 5), Decl(enumDef.js, 3, 5), Decl(enumDef.js, 10, 26) ... and 1 more) ->Host : Symbol(Host, Decl(enumDef.js, 0, 3), Decl(enumDef.js, 0, 14), Decl(enumDef.js, 1, 22), Decl(enumDef.js, 8, 2), Decl(enumDef.js, 1, 22) ... and 2 more) ->UserMetrics : Symbol(Host.UserMetrics, Decl(enumDef.js, 0, 14), Decl(enumDef.js, 3, 5), Decl(enumDef.js, 15, 5), Decl(enumDef.js, 3, 5), Decl(enumDef.js, 10, 26) ... and 1 more) +>Host.UserMetrics : Symbol(Host.UserMetrics, Decl(enumDef.js, 0, 14), Decl(enumDef.js, 3, 5), Decl(enumDef.js, 15, 5), Decl(enumDef.js, 10, 26)) +>Host : Symbol(Host, Decl(enumDef.js, 0, 3), Decl(enumDef.js, 0, 14), Decl(enumDef.js, 1, 22), Decl(enumDef.js, 8, 2), Decl(enumDef.js, 10, 21)) +>UserMetrics : Symbol(Host.UserMetrics, Decl(enumDef.js, 0, 14), Decl(enumDef.js, 3, 5), Decl(enumDef.js, 15, 5), Decl(enumDef.js, 10, 26)) /** @enum {number} */ Host.UserMetrics.Action = { >Host.UserMetrics.Action : Symbol(Host.UserMetrics.Action, Decl(enumDef.js, 1, 22), Decl(enumDef.js, 3, 17), Decl(enumDef.js, 2, 4)) ->Host.UserMetrics : Symbol(Host.UserMetrics, Decl(enumDef.js, 0, 14), Decl(enumDef.js, 3, 5), Decl(enumDef.js, 15, 5), Decl(enumDef.js, 3, 5), Decl(enumDef.js, 10, 26) ... and 1 more) ->Host : Symbol(Host, Decl(enumDef.js, 0, 3), Decl(enumDef.js, 0, 14), Decl(enumDef.js, 1, 22), Decl(enumDef.js, 8, 2), Decl(enumDef.js, 1, 22) ... and 2 more) ->UserMetrics : Symbol(Host.UserMetrics, Decl(enumDef.js, 0, 14), Decl(enumDef.js, 3, 5), Decl(enumDef.js, 15, 5), Decl(enumDef.js, 3, 5), Decl(enumDef.js, 10, 26) ... and 1 more) +>Host.UserMetrics : Symbol(Host.UserMetrics, Decl(enumDef.js, 0, 14), Decl(enumDef.js, 3, 5), Decl(enumDef.js, 15, 5), Decl(enumDef.js, 10, 26)) +>Host : Symbol(Host, Decl(enumDef.js, 0, 3), Decl(enumDef.js, 0, 14), Decl(enumDef.js, 1, 22), Decl(enumDef.js, 8, 2), Decl(enumDef.js, 10, 21)) +>UserMetrics : Symbol(Host.UserMetrics, Decl(enumDef.js, 0, 14), Decl(enumDef.js, 3, 5), Decl(enumDef.js, 15, 5), Decl(enumDef.js, 10, 26)) >Action : Symbol(Host.UserMetrics.Action, Decl(enumDef.js, 1, 22), Decl(enumDef.js, 3, 17), Decl(enumDef.js, 2, 4)) WindowDocked: 1, @@ -36,9 +36,9 @@ Host.UserMetrics.Action = { */ Host.UserMetrics.Blah = { >Host.UserMetrics.Blah : Symbol(Host.UserMetrics.Blah, Decl(enumDef.js, 8, 2), Decl(enumDef.js, 15, 17), Decl(enumDef.js, 13, 3)) ->Host.UserMetrics : Symbol(Host.UserMetrics, Decl(enumDef.js, 0, 14), Decl(enumDef.js, 3, 5), Decl(enumDef.js, 15, 5), Decl(enumDef.js, 3, 5), Decl(enumDef.js, 10, 26) ... and 1 more) ->Host : Symbol(Host, Decl(enumDef.js, 0, 3), Decl(enumDef.js, 0, 14), Decl(enumDef.js, 1, 22), Decl(enumDef.js, 8, 2), Decl(enumDef.js, 1, 22) ... and 2 more) ->UserMetrics : Symbol(Host.UserMetrics, Decl(enumDef.js, 0, 14), Decl(enumDef.js, 3, 5), Decl(enumDef.js, 15, 5), Decl(enumDef.js, 3, 5), Decl(enumDef.js, 10, 26) ... and 1 more) +>Host.UserMetrics : Symbol(Host.UserMetrics, Decl(enumDef.js, 0, 14), Decl(enumDef.js, 3, 5), Decl(enumDef.js, 15, 5), Decl(enumDef.js, 10, 26)) +>Host : Symbol(Host, Decl(enumDef.js, 0, 3), Decl(enumDef.js, 0, 14), Decl(enumDef.js, 1, 22), Decl(enumDef.js, 8, 2), Decl(enumDef.js, 10, 21)) +>UserMetrics : Symbol(Host.UserMetrics, Decl(enumDef.js, 0, 14), Decl(enumDef.js, 3, 5), Decl(enumDef.js, 15, 5), Decl(enumDef.js, 10, 26)) >Blah : Symbol(Host.UserMetrics.Blah, Decl(enumDef.js, 8, 2), Decl(enumDef.js, 15, 17), Decl(enumDef.js, 13, 3)) x: 12 @@ -68,9 +68,9 @@ Other.Cls = class { >this : Symbol(Cls, Decl(index.js, 1, 11)) >method : Symbol(Cls.method, Decl(index.js, 1, 19)) >Host.UserMetrics.Action : Symbol(Host.UserMetrics.Action, Decl(enumDef.js, 1, 22), Decl(enumDef.js, 3, 17), Decl(enumDef.js, 2, 4)) ->Host.UserMetrics : Symbol(Host.UserMetrics, Decl(enumDef.js, 0, 14), Decl(enumDef.js, 3, 5), Decl(enumDef.js, 15, 5), Decl(enumDef.js, 3, 5), Decl(enumDef.js, 10, 26) ... and 1 more) ->Host : Symbol(Host, Decl(enumDef.js, 0, 3), Decl(enumDef.js, 0, 14), Decl(enumDef.js, 1, 22), Decl(enumDef.js, 8, 2), Decl(enumDef.js, 1, 22) ... and 2 more) ->UserMetrics : Symbol(Host.UserMetrics, Decl(enumDef.js, 0, 14), Decl(enumDef.js, 3, 5), Decl(enumDef.js, 15, 5), Decl(enumDef.js, 3, 5), Decl(enumDef.js, 10, 26) ... and 1 more) +>Host.UserMetrics : Symbol(Host.UserMetrics, Decl(enumDef.js, 0, 14), Decl(enumDef.js, 3, 5), Decl(enumDef.js, 15, 5), Decl(enumDef.js, 10, 26)) +>Host : Symbol(Host, Decl(enumDef.js, 0, 3), Decl(enumDef.js, 0, 14), Decl(enumDef.js, 1, 22), Decl(enumDef.js, 8, 2), Decl(enumDef.js, 10, 21)) +>UserMetrics : Symbol(Host.UserMetrics, Decl(enumDef.js, 0, 14), Decl(enumDef.js, 3, 5), Decl(enumDef.js, 15, 5), Decl(enumDef.js, 10, 26)) >Action : Symbol(Host.UserMetrics.Action, Decl(enumDef.js, 1, 22), Decl(enumDef.js, 3, 17), Decl(enumDef.js, 2, 4)) } } diff --git a/tests/baselines/reference/jsFunctionWithPrototypeNoErrorTruncationNoCrash.errors.txt b/tests/baselines/reference/jsFunctionWithPrototypeNoErrorTruncationNoCrash.errors.txt index f4f41b4e231..fa2eca55e75 100644 --- a/tests/baselines/reference/jsFunctionWithPrototypeNoErrorTruncationNoCrash.errors.txt +++ b/tests/baselines/reference/jsFunctionWithPrototypeNoErrorTruncationNoCrash.errors.txt @@ -6,11 +6,10 @@ tests/cases/compiler/index.js(9,24): error TS7006: Parameter 'ratio' implicitly tests/cases/compiler/index.js(10,20): error TS7006: Parameter 'ratio' implicitly has an 'any' type. tests/cases/compiler/index.js(11,21): error TS7006: Parameter 'ratio' implicitly has an 'any' type. tests/cases/compiler/index.js(13,21): error TS7006: Parameter 'ratio' implicitly has an 'any' type. -tests/cases/compiler/index.js(14,2): error TS7023: 'toJSON' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. -tests/cases/compiler/index.js(14,35): error TS2339: Property 'rgb' does not exist on type 'Color & { negate: () => Color & any; lighten: (ratio: any) => Color & any; darken: (ratio: any) => Color & any; saturate: (ratio: any) => Color & any; desaturate: (ratio: any) => Color & any; whiten: (ratio: any) => Color & any; blacken: (ratio: any) => Color & any; greyscale: () => Color & any; clearer: (ratio: any) => Color & any; toJSON: () => any; }'. +tests/cases/compiler/index.js(14,35): error TS2339: Property 'rgb' does not exist on type 'Color'. -==== tests/cases/compiler/index.js (10 errors) ==== +==== tests/cases/compiler/index.js (9 errors) ==== function Color(obj) { ~~~ !!! error TS7006: Parameter 'obj' implicitly has an 'any' type. @@ -41,8 +40,6 @@ tests/cases/compiler/index.js(14,35): error TS2339: Property 'rgb' does not exis ~~~~~ !!! error TS7006: Parameter 'ratio' implicitly has an 'any' type. toJSON: function () {return this.rgb();}, - ~~~~~~ -!!! error TS7023: 'toJSON' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. ~~~ -!!! error TS2339: Property 'rgb' does not exist on type 'Color & { negate: () => Color & any; lighten: (ratio: any) => Color & any; darken: (ratio: any) => Color & any; saturate: (ratio: any) => Color & any; desaturate: (ratio: any) => Color & any; whiten: (ratio: any) => Color & any; blacken: (ratio: any) => Color & any; greyscale: () => Color & any; clearer: (ratio: any) => Color & any; toJSON: () => any; }'. +!!! error TS2339: Property 'rgb' does not exist on type 'Color'. }; \ No newline at end of file diff --git a/tests/baselines/reference/jsFunctionWithPrototypeNoErrorTruncationNoCrash.symbols b/tests/baselines/reference/jsFunctionWithPrototypeNoErrorTruncationNoCrash.symbols index 992df4b7886..d2bb8c9079c 100644 --- a/tests/baselines/reference/jsFunctionWithPrototypeNoErrorTruncationNoCrash.symbols +++ b/tests/baselines/reference/jsFunctionWithPrototypeNoErrorTruncationNoCrash.symbols @@ -14,39 +14,49 @@ Color.prototype = { negate: function () {return this;}, >negate : Symbol(negate, Decl(index.js, 3, 19)) +>this : Symbol(Color, Decl(index.js, 0, 0), Decl(index.js, 2, 2)) lighten: function (ratio) {return this;}, >lighten : Symbol(lighten, Decl(index.js, 4, 36)) >ratio : Symbol(ratio, Decl(index.js, 5, 20)) +>this : Symbol(Color, Decl(index.js, 0, 0), Decl(index.js, 2, 2)) darken: function (ratio) {return this;}, >darken : Symbol(darken, Decl(index.js, 5, 42)) >ratio : Symbol(ratio, Decl(index.js, 6, 19)) +>this : Symbol(Color, Decl(index.js, 0, 0), Decl(index.js, 2, 2)) saturate: function (ratio) {return this;}, >saturate : Symbol(saturate, Decl(index.js, 6, 41)) >ratio : Symbol(ratio, Decl(index.js, 7, 21)) +>this : Symbol(Color, Decl(index.js, 0, 0), Decl(index.js, 2, 2)) desaturate: function (ratio) {return this;}, >desaturate : Symbol(desaturate, Decl(index.js, 7, 43)) >ratio : Symbol(ratio, Decl(index.js, 8, 23)) +>this : Symbol(Color, Decl(index.js, 0, 0), Decl(index.js, 2, 2)) whiten: function (ratio) {return this;}, >whiten : Symbol(whiten, Decl(index.js, 8, 45)) >ratio : Symbol(ratio, Decl(index.js, 9, 19)) +>this : Symbol(Color, Decl(index.js, 0, 0), Decl(index.js, 2, 2)) blacken: function (ratio) {return this;}, >blacken : Symbol(blacken, Decl(index.js, 9, 41)) >ratio : Symbol(ratio, Decl(index.js, 10, 20)) +>this : Symbol(Color, Decl(index.js, 0, 0), Decl(index.js, 2, 2)) greyscale: function () {return this;}, >greyscale : Symbol(greyscale, Decl(index.js, 10, 42)) +>this : Symbol(Color, Decl(index.js, 0, 0), Decl(index.js, 2, 2)) clearer: function (ratio) {return this;}, >clearer : Symbol(clearer, Decl(index.js, 11, 39)) >ratio : Symbol(ratio, Decl(index.js, 12, 20)) +>this : Symbol(Color, Decl(index.js, 0, 0), Decl(index.js, 2, 2)) toJSON: function () {return this.rgb();}, >toJSON : Symbol(toJSON, Decl(index.js, 12, 42)) +>this : Symbol(Color, Decl(index.js, 0, 0), Decl(index.js, 2, 2)) }; diff --git a/tests/baselines/reference/jsFunctionWithPrototypeNoErrorTruncationNoCrash.types b/tests/baselines/reference/jsFunctionWithPrototypeNoErrorTruncationNoCrash.types index e7d10c54453..5d547a666e8 100644 --- a/tests/baselines/reference/jsFunctionWithPrototypeNoErrorTruncationNoCrash.types +++ b/tests/baselines/reference/jsFunctionWithPrototypeNoErrorTruncationNoCrash.types @@ -12,70 +12,70 @@ function Color(obj) { }; Color.prototype = { ->Color.prototype = { negate: function () {return this;}, lighten: function (ratio) {return this;}, darken: function (ratio) {return this;}, saturate: function (ratio) {return this;}, desaturate: function (ratio) {return this;}, whiten: function (ratio) {return this;}, blacken: function (ratio) {return this;}, greyscale: function () {return this;}, clearer: function (ratio) {return this;}, toJSON: function () {return this.rgb();},} : { negate: () => Color & { negate: any; lighten: (ratio: any) => Color & any; darken: (ratio: any) => Color & any; saturate: (ratio: any) => Color & any; desaturate: (ratio: any) => Color & any; whiten: (ratio: any) => Color & any; blacken: (ratio: any) => Color & any; greyscale: () => Color & any; clearer: (ratio: any) => Color & any; toJSON: () => any; }; lighten: (ratio: any) => Color & { negate: () => Color & any; lighten: any; darken: (ratio: any) => Color & any; saturate: (ratio: any) => Color & any; desaturate: (ratio: any) => Color & any; whiten: (ratio: any) => Color & any; blacken: (ratio: any) => Color & any; greyscale: () => Color & any; clearer: (ratio: any) => Color & any; toJSON: () => any; }; darken: (ratio: any) => Color & { negate: () => Color & any; lighten: (ratio: any) => Color & any; darken: any; saturate: (ratio: any) => Color & any; desaturate: (ratio: any) => Color & any; whiten: (ratio: any) => Color & any; blacken: (ratio: any) => Color & any; greyscale: () => Color & any; clearer: (ratio: any) => Color & any; toJSON: () => any; }; saturate: (ratio: any) => Color & { negate: () => Color & any; lighten: (ratio: any) => Color & any; darken: (ratio: any) => Color & any; saturate: any; desaturate: (ratio: any) => Color & any; whiten: (ratio: any) => Color & any; blacken: (ratio: any) => Color & any; greyscale: () => Color & any; clearer: (ratio: any) => Color & any; toJSON: () => any; }; desaturate: (ratio: any) => Color & { negate: () => Color & any; lighten: (ratio: any) => Color & any; darken: (ratio: any) => Color & any; saturate: (ratio: any) => Color & any; desaturate: any; whiten: (ratio: any) => Color & any; blacken: (ratio: any) => Color & any; greyscale: () => Color & any; clearer: (ratio: any) => Color & any; toJSON: () => any; }; whiten: (ratio: any) => Color & { negate: () => Color & any; lighten: (ratio: any) => Color & any; darken: (ratio: any) => Color & any; saturate: (ratio: any) => Color & any; desaturate: (ratio: any) => Color & any; whiten: any; blacken: (ratio: any) => Color & any; greyscale: () => Color & any; clearer: (ratio: any) => Color & any; toJSON: () => any; }; blacken: (ratio: any) => Color & { negate: () => Color & any; lighten: (ratio: any) => Color & any; darken: (ratio: any) => Color & any; saturate: (ratio: any) => Color & any; desaturate: (ratio: any) => Color & any; whiten: (ratio: any) => Color & any; blacken: any; greyscale: () => Color & any; clearer: (ratio: any) => Color & any; toJSON: () => any; }; greyscale: () => Color & { negate: () => Color & any; lighten: (ratio: any) => Color & any; darken: (ratio: any) => Color & any; saturate: (ratio: any) => Color & any; desaturate: (ratio: any) => Color & any; whiten: (ratio: any) => Color & any; blacken: (ratio: any) => Color & any; greyscale: any; clearer: (ratio: any) => Color & any; toJSON: () => any; }; clearer: (ratio: any) => Color & { negate: () => Color & any; lighten: (ratio: any) => Color & any; darken: (ratio: any) => Color & any; saturate: (ratio: any) => Color & any; desaturate: (ratio: any) => Color & any; whiten: (ratio: any) => Color & any; blacken: (ratio: any) => Color & any; greyscale: () => Color & any; clearer: any; toJSON: () => any; }; toJSON: () => any; } ->Color.prototype : { negate: () => Color & { negate: any; lighten: (ratio: any) => Color & any; darken: (ratio: any) => Color & any; saturate: (ratio: any) => Color & any; desaturate: (ratio: any) => Color & any; whiten: (ratio: any) => Color & any; blacken: (ratio: any) => Color & any; greyscale: () => Color & any; clearer: (ratio: any) => Color & any; toJSON: () => any; }; lighten: (ratio: any) => Color & { negate: () => Color & any; lighten: any; darken: (ratio: any) => Color & any; saturate: (ratio: any) => Color & any; desaturate: (ratio: any) => Color & any; whiten: (ratio: any) => Color & any; blacken: (ratio: any) => Color & any; greyscale: () => Color & any; clearer: (ratio: any) => Color & any; toJSON: () => any; }; darken: (ratio: any) => Color & { negate: () => Color & any; lighten: (ratio: any) => Color & any; darken: any; saturate: (ratio: any) => Color & any; desaturate: (ratio: any) => Color & any; whiten: (ratio: any) => Color & any; blacken: (ratio: any) => Color & any; greyscale: () => Color & any; clearer: (ratio: any) => Color & any; toJSON: () => any; }; saturate: (ratio: any) => Color & { negate: () => Color & any; lighten: (ratio: any) => Color & any; darken: (ratio: any) => Color & any; saturate: any; desaturate: (ratio: any) => Color & any; whiten: (ratio: any) => Color & any; blacken: (ratio: any) => Color & any; greyscale: () => Color & any; clearer: (ratio: any) => Color & any; toJSON: () => any; }; desaturate: (ratio: any) => Color & { negate: () => Color & any; lighten: (ratio: any) => Color & any; darken: (ratio: any) => Color & any; saturate: (ratio: any) => Color & any; desaturate: any; whiten: (ratio: any) => Color & any; blacken: (ratio: any) => Color & any; greyscale: () => Color & any; clearer: (ratio: any) => Color & any; toJSON: () => any; }; whiten: (ratio: any) => Color & { negate: () => Color & any; lighten: (ratio: any) => Color & any; darken: (ratio: any) => Color & any; saturate: (ratio: any) => Color & any; desaturate: (ratio: any) => Color & any; whiten: any; blacken: (ratio: any) => Color & any; greyscale: () => Color & any; clearer: (ratio: any) => Color & any; toJSON: () => any; }; blacken: (ratio: any) => Color & { negate: () => Color & any; lighten: (ratio: any) => Color & any; darken: (ratio: any) => Color & any; saturate: (ratio: any) => Color & any; desaturate: (ratio: any) => Color & any; whiten: (ratio: any) => Color & any; blacken: any; greyscale: () => Color & any; clearer: (ratio: any) => Color & any; toJSON: () => any; }; greyscale: () => Color & { negate: () => Color & any; lighten: (ratio: any) => Color & any; darken: (ratio: any) => Color & any; saturate: (ratio: any) => Color & any; desaturate: (ratio: any) => Color & any; whiten: (ratio: any) => Color & any; blacken: (ratio: any) => Color & any; greyscale: any; clearer: (ratio: any) => Color & any; toJSON: () => any; }; clearer: (ratio: any) => Color & { negate: () => Color & any; lighten: (ratio: any) => Color & any; darken: (ratio: any) => Color & any; saturate: (ratio: any) => Color & any; desaturate: (ratio: any) => Color & any; whiten: (ratio: any) => Color & any; blacken: (ratio: any) => Color & any; greyscale: () => Color & any; clearer: any; toJSON: () => any; }; toJSON: () => any; } +>Color.prototype = { negate: function () {return this;}, lighten: function (ratio) {return this;}, darken: function (ratio) {return this;}, saturate: function (ratio) {return this;}, desaturate: function (ratio) {return this;}, whiten: function (ratio) {return this;}, blacken: function (ratio) {return this;}, greyscale: function () {return this;}, clearer: function (ratio) {return this;}, toJSON: function () {return this.rgb();},} : { negate: () => this; lighten: (ratio: any) => this; darken: (ratio: any) => this; saturate: (ratio: any) => this; desaturate: (ratio: any) => this; whiten: (ratio: any) => this; blacken: (ratio: any) => this; greyscale: () => this; clearer: (ratio: any) => this; toJSON: () => any; } +>Color.prototype : { negate: () => this; lighten: (ratio: any) => this; darken: (ratio: any) => this; saturate: (ratio: any) => this; desaturate: (ratio: any) => this; whiten: (ratio: any) => this; blacken: (ratio: any) => this; greyscale: () => this; clearer: (ratio: any) => this; toJSON: () => any; } >Color : typeof Color ->prototype : { negate: () => Color & { negate: any; lighten: (ratio: any) => Color & any; darken: (ratio: any) => Color & any; saturate: (ratio: any) => Color & any; desaturate: (ratio: any) => Color & any; whiten: (ratio: any) => Color & any; blacken: (ratio: any) => Color & any; greyscale: () => Color & any; clearer: (ratio: any) => Color & any; toJSON: () => any; }; lighten: (ratio: any) => Color & { negate: () => Color & any; lighten: any; darken: (ratio: any) => Color & any; saturate: (ratio: any) => Color & any; desaturate: (ratio: any) => Color & any; whiten: (ratio: any) => Color & any; blacken: (ratio: any) => Color & any; greyscale: () => Color & any; clearer: (ratio: any) => Color & any; toJSON: () => any; }; darken: (ratio: any) => Color & { negate: () => Color & any; lighten: (ratio: any) => Color & any; darken: any; saturate: (ratio: any) => Color & any; desaturate: (ratio: any) => Color & any; whiten: (ratio: any) => Color & any; blacken: (ratio: any) => Color & any; greyscale: () => Color & any; clearer: (ratio: any) => Color & any; toJSON: () => any; }; saturate: (ratio: any) => Color & { negate: () => Color & any; lighten: (ratio: any) => Color & any; darken: (ratio: any) => Color & any; saturate: any; desaturate: (ratio: any) => Color & any; whiten: (ratio: any) => Color & any; blacken: (ratio: any) => Color & any; greyscale: () => Color & any; clearer: (ratio: any) => Color & any; toJSON: () => any; }; desaturate: (ratio: any) => Color & { negate: () => Color & any; lighten: (ratio: any) => Color & any; darken: (ratio: any) => Color & any; saturate: (ratio: any) => Color & any; desaturate: any; whiten: (ratio: any) => Color & any; blacken: (ratio: any) => Color & any; greyscale: () => Color & any; clearer: (ratio: any) => Color & any; toJSON: () => any; }; whiten: (ratio: any) => Color & { negate: () => Color & any; lighten: (ratio: any) => Color & any; darken: (ratio: any) => Color & any; saturate: (ratio: any) => Color & any; desaturate: (ratio: any) => Color & any; whiten: any; blacken: (ratio: any) => Color & any; greyscale: () => Color & any; clearer: (ratio: any) => Color & any; toJSON: () => any; }; blacken: (ratio: any) => Color & { negate: () => Color & any; lighten: (ratio: any) => Color & any; darken: (ratio: any) => Color & any; saturate: (ratio: any) => Color & any; desaturate: (ratio: any) => Color & any; whiten: (ratio: any) => Color & any; blacken: any; greyscale: () => Color & any; clearer: (ratio: any) => Color & any; toJSON: () => any; }; greyscale: () => Color & { negate: () => Color & any; lighten: (ratio: any) => Color & any; darken: (ratio: any) => Color & any; saturate: (ratio: any) => Color & any; desaturate: (ratio: any) => Color & any; whiten: (ratio: any) => Color & any; blacken: (ratio: any) => Color & any; greyscale: any; clearer: (ratio: any) => Color & any; toJSON: () => any; }; clearer: (ratio: any) => Color & { negate: () => Color & any; lighten: (ratio: any) => Color & any; darken: (ratio: any) => Color & any; saturate: (ratio: any) => Color & any; desaturate: (ratio: any) => Color & any; whiten: (ratio: any) => Color & any; blacken: (ratio: any) => Color & any; greyscale: () => Color & any; clearer: any; toJSON: () => any; }; toJSON: () => any; } ->{ negate: function () {return this;}, lighten: function (ratio) {return this;}, darken: function (ratio) {return this;}, saturate: function (ratio) {return this;}, desaturate: function (ratio) {return this;}, whiten: function (ratio) {return this;}, blacken: function (ratio) {return this;}, greyscale: function () {return this;}, clearer: function (ratio) {return this;}, toJSON: function () {return this.rgb();},} : { negate: () => Color & { negate: any; lighten: (ratio: any) => Color & any; darken: (ratio: any) => Color & any; saturate: (ratio: any) => Color & any; desaturate: (ratio: any) => Color & any; whiten: (ratio: any) => Color & any; blacken: (ratio: any) => Color & any; greyscale: () => Color & any; clearer: (ratio: any) => Color & any; toJSON: () => any; }; lighten: (ratio: any) => Color & { negate: () => Color & any; lighten: any; darken: (ratio: any) => Color & any; saturate: (ratio: any) => Color & any; desaturate: (ratio: any) => Color & any; whiten: (ratio: any) => Color & any; blacken: (ratio: any) => Color & any; greyscale: () => Color & any; clearer: (ratio: any) => Color & any; toJSON: () => any; }; darken: (ratio: any) => Color & { negate: () => Color & any; lighten: (ratio: any) => Color & any; darken: any; saturate: (ratio: any) => Color & any; desaturate: (ratio: any) => Color & any; whiten: (ratio: any) => Color & any; blacken: (ratio: any) => Color & any; greyscale: () => Color & any; clearer: (ratio: any) => Color & any; toJSON: () => any; }; saturate: (ratio: any) => Color & { negate: () => Color & any; lighten: (ratio: any) => Color & any; darken: (ratio: any) => Color & any; saturate: any; desaturate: (ratio: any) => Color & any; whiten: (ratio: any) => Color & any; blacken: (ratio: any) => Color & any; greyscale: () => Color & any; clearer: (ratio: any) => Color & any; toJSON: () => any; }; desaturate: (ratio: any) => Color & { negate: () => Color & any; lighten: (ratio: any) => Color & any; darken: (ratio: any) => Color & any; saturate: (ratio: any) => Color & any; desaturate: any; whiten: (ratio: any) => Color & any; blacken: (ratio: any) => Color & any; greyscale: () => Color & any; clearer: (ratio: any) => Color & any; toJSON: () => any; }; whiten: (ratio: any) => Color & { negate: () => Color & any; lighten: (ratio: any) => Color & any; darken: (ratio: any) => Color & any; saturate: (ratio: any) => Color & any; desaturate: (ratio: any) => Color & any; whiten: any; blacken: (ratio: any) => Color & any; greyscale: () => Color & any; clearer: (ratio: any) => Color & any; toJSON: () => any; }; blacken: (ratio: any) => Color & { negate: () => Color & any; lighten: (ratio: any) => Color & any; darken: (ratio: any) => Color & any; saturate: (ratio: any) => Color & any; desaturate: (ratio: any) => Color & any; whiten: (ratio: any) => Color & any; blacken: any; greyscale: () => Color & any; clearer: (ratio: any) => Color & any; toJSON: () => any; }; greyscale: () => Color & { negate: () => Color & any; lighten: (ratio: any) => Color & any; darken: (ratio: any) => Color & any; saturate: (ratio: any) => Color & any; desaturate: (ratio: any) => Color & any; whiten: (ratio: any) => Color & any; blacken: (ratio: any) => Color & any; greyscale: any; clearer: (ratio: any) => Color & any; toJSON: () => any; }; clearer: (ratio: any) => Color & { negate: () => Color & any; lighten: (ratio: any) => Color & any; darken: (ratio: any) => Color & any; saturate: (ratio: any) => Color & any; desaturate: (ratio: any) => Color & any; whiten: (ratio: any) => Color & any; blacken: (ratio: any) => Color & any; greyscale: () => Color & any; clearer: any; toJSON: () => any; }; toJSON: () => any; } +>prototype : { negate: () => this; lighten: (ratio: any) => this; darken: (ratio: any) => this; saturate: (ratio: any) => this; desaturate: (ratio: any) => this; whiten: (ratio: any) => this; blacken: (ratio: any) => this; greyscale: () => this; clearer: (ratio: any) => this; toJSON: () => any; } +>{ negate: function () {return this;}, lighten: function (ratio) {return this;}, darken: function (ratio) {return this;}, saturate: function (ratio) {return this;}, desaturate: function (ratio) {return this;}, whiten: function (ratio) {return this;}, blacken: function (ratio) {return this;}, greyscale: function () {return this;}, clearer: function (ratio) {return this;}, toJSON: function () {return this.rgb();},} : { negate: () => this; lighten: (ratio: any) => this; darken: (ratio: any) => this; saturate: (ratio: any) => this; desaturate: (ratio: any) => this; whiten: (ratio: any) => this; blacken: (ratio: any) => this; greyscale: () => this; clearer: (ratio: any) => this; toJSON: () => any; } negate: function () {return this;}, ->negate : () => Color & { negate: any; lighten: (ratio: any) => Color & any; darken: (ratio: any) => Color & any; saturate: (ratio: any) => Color & any; desaturate: (ratio: any) => Color & any; whiten: (ratio: any) => Color & any; blacken: (ratio: any) => Color & any; greyscale: () => Color & any; clearer: (ratio: any) => Color & any; toJSON: () => any; } ->function () {return this;} : () => Color & { negate: any; lighten: (ratio: any) => Color & any; darken: (ratio: any) => Color & any; saturate: (ratio: any) => Color & any; desaturate: (ratio: any) => Color & any; whiten: (ratio: any) => Color & any; blacken: (ratio: any) => Color & any; greyscale: () => Color & any; clearer: (ratio: any) => Color & any; toJSON: () => any; } ->this : Color & { negate: () => Color & any; lighten: (ratio: any) => Color & any; darken: (ratio: any) => Color & any; saturate: (ratio: any) => Color & any; desaturate: (ratio: any) => Color & any; whiten: (ratio: any) => Color & any; blacken: (ratio: any) => Color & any; greyscale: () => Color & any; clearer: (ratio: any) => Color & any; toJSON: () => any; } +>negate : () => this +>function () {return this;} : () => this +>this : this lighten: function (ratio) {return this;}, ->lighten : (ratio: any) => Color & { negate: () => Color & any; lighten: any; darken: (ratio: any) => Color & any; saturate: (ratio: any) => Color & any; desaturate: (ratio: any) => Color & any; whiten: (ratio: any) => Color & any; blacken: (ratio: any) => Color & any; greyscale: () => Color & any; clearer: (ratio: any) => Color & any; toJSON: () => any; } ->function (ratio) {return this;} : (ratio: any) => Color & { negate: () => Color & any; lighten: any; darken: (ratio: any) => Color & any; saturate: (ratio: any) => Color & any; desaturate: (ratio: any) => Color & any; whiten: (ratio: any) => Color & any; blacken: (ratio: any) => Color & any; greyscale: () => Color & any; clearer: (ratio: any) => Color & any; toJSON: () => any; } +>lighten : (ratio: any) => this +>function (ratio) {return this;} : (ratio: any) => this >ratio : any ->this : Color & { negate: () => Color & any; lighten: (ratio: any) => Color & any; darken: (ratio: any) => Color & any; saturate: (ratio: any) => Color & any; desaturate: (ratio: any) => Color & any; whiten: (ratio: any) => Color & any; blacken: (ratio: any) => Color & any; greyscale: () => Color & any; clearer: (ratio: any) => Color & any; toJSON: () => any; } +>this : this darken: function (ratio) {return this;}, ->darken : (ratio: any) => Color & { negate: () => Color & any; lighten: (ratio: any) => Color & any; darken: any; saturate: (ratio: any) => Color & any; desaturate: (ratio: any) => Color & any; whiten: (ratio: any) => Color & any; blacken: (ratio: any) => Color & any; greyscale: () => Color & any; clearer: (ratio: any) => Color & any; toJSON: () => any; } ->function (ratio) {return this;} : (ratio: any) => Color & { negate: () => Color & any; lighten: (ratio: any) => Color & any; darken: any; saturate: (ratio: any) => Color & any; desaturate: (ratio: any) => Color & any; whiten: (ratio: any) => Color & any; blacken: (ratio: any) => Color & any; greyscale: () => Color & any; clearer: (ratio: any) => Color & any; toJSON: () => any; } +>darken : (ratio: any) => this +>function (ratio) {return this;} : (ratio: any) => this >ratio : any ->this : Color & { negate: () => Color & any; lighten: (ratio: any) => Color & any; darken: (ratio: any) => Color & any; saturate: (ratio: any) => Color & any; desaturate: (ratio: any) => Color & any; whiten: (ratio: any) => Color & any; blacken: (ratio: any) => Color & any; greyscale: () => Color & any; clearer: (ratio: any) => Color & any; toJSON: () => any; } +>this : this saturate: function (ratio) {return this;}, ->saturate : (ratio: any) => Color & { negate: () => Color & any; lighten: (ratio: any) => Color & any; darken: (ratio: any) => Color & any; saturate: any; desaturate: (ratio: any) => Color & any; whiten: (ratio: any) => Color & any; blacken: (ratio: any) => Color & any; greyscale: () => Color & any; clearer: (ratio: any) => Color & any; toJSON: () => any; } ->function (ratio) {return this;} : (ratio: any) => Color & { negate: () => Color & any; lighten: (ratio: any) => Color & any; darken: (ratio: any) => Color & any; saturate: any; desaturate: (ratio: any) => Color & any; whiten: (ratio: any) => Color & any; blacken: (ratio: any) => Color & any; greyscale: () => Color & any; clearer: (ratio: any) => Color & any; toJSON: () => any; } +>saturate : (ratio: any) => this +>function (ratio) {return this;} : (ratio: any) => this >ratio : any ->this : Color & { negate: () => Color & any; lighten: (ratio: any) => Color & any; darken: (ratio: any) => Color & any; saturate: (ratio: any) => Color & any; desaturate: (ratio: any) => Color & any; whiten: (ratio: any) => Color & any; blacken: (ratio: any) => Color & any; greyscale: () => Color & any; clearer: (ratio: any) => Color & any; toJSON: () => any; } +>this : this desaturate: function (ratio) {return this;}, ->desaturate : (ratio: any) => Color & { negate: () => Color & any; lighten: (ratio: any) => Color & any; darken: (ratio: any) => Color & any; saturate: (ratio: any) => Color & any; desaturate: any; whiten: (ratio: any) => Color & any; blacken: (ratio: any) => Color & any; greyscale: () => Color & any; clearer: (ratio: any) => Color & any; toJSON: () => any; } ->function (ratio) {return this;} : (ratio: any) => Color & { negate: () => Color & any; lighten: (ratio: any) => Color & any; darken: (ratio: any) => Color & any; saturate: (ratio: any) => Color & any; desaturate: any; whiten: (ratio: any) => Color & any; blacken: (ratio: any) => Color & any; greyscale: () => Color & any; clearer: (ratio: any) => Color & any; toJSON: () => any; } +>desaturate : (ratio: any) => this +>function (ratio) {return this;} : (ratio: any) => this >ratio : any ->this : Color & { negate: () => Color & any; lighten: (ratio: any) => Color & any; darken: (ratio: any) => Color & any; saturate: (ratio: any) => Color & any; desaturate: (ratio: any) => Color & any; whiten: (ratio: any) => Color & any; blacken: (ratio: any) => Color & any; greyscale: () => Color & any; clearer: (ratio: any) => Color & any; toJSON: () => any; } +>this : this whiten: function (ratio) {return this;}, ->whiten : (ratio: any) => Color & { negate: () => Color & any; lighten: (ratio: any) => Color & any; darken: (ratio: any) => Color & any; saturate: (ratio: any) => Color & any; desaturate: (ratio: any) => Color & any; whiten: any; blacken: (ratio: any) => Color & any; greyscale: () => Color & any; clearer: (ratio: any) => Color & any; toJSON: () => any; } ->function (ratio) {return this;} : (ratio: any) => Color & { negate: () => Color & any; lighten: (ratio: any) => Color & any; darken: (ratio: any) => Color & any; saturate: (ratio: any) => Color & any; desaturate: (ratio: any) => Color & any; whiten: any; blacken: (ratio: any) => Color & any; greyscale: () => Color & any; clearer: (ratio: any) => Color & any; toJSON: () => any; } +>whiten : (ratio: any) => this +>function (ratio) {return this;} : (ratio: any) => this >ratio : any ->this : Color & { negate: () => Color & any; lighten: (ratio: any) => Color & any; darken: (ratio: any) => Color & any; saturate: (ratio: any) => Color & any; desaturate: (ratio: any) => Color & any; whiten: (ratio: any) => Color & any; blacken: (ratio: any) => Color & any; greyscale: () => Color & any; clearer: (ratio: any) => Color & any; toJSON: () => any; } +>this : this blacken: function (ratio) {return this;}, ->blacken : (ratio: any) => Color & { negate: () => Color & any; lighten: (ratio: any) => Color & any; darken: (ratio: any) => Color & any; saturate: (ratio: any) => Color & any; desaturate: (ratio: any) => Color & any; whiten: (ratio: any) => Color & any; blacken: any; greyscale: () => Color & any; clearer: (ratio: any) => Color & any; toJSON: () => any; } ->function (ratio) {return this;} : (ratio: any) => Color & { negate: () => Color & any; lighten: (ratio: any) => Color & any; darken: (ratio: any) => Color & any; saturate: (ratio: any) => Color & any; desaturate: (ratio: any) => Color & any; whiten: (ratio: any) => Color & any; blacken: any; greyscale: () => Color & any; clearer: (ratio: any) => Color & any; toJSON: () => any; } +>blacken : (ratio: any) => this +>function (ratio) {return this;} : (ratio: any) => this >ratio : any ->this : Color & { negate: () => Color & any; lighten: (ratio: any) => Color & any; darken: (ratio: any) => Color & any; saturate: (ratio: any) => Color & any; desaturate: (ratio: any) => Color & any; whiten: (ratio: any) => Color & any; blacken: (ratio: any) => Color & any; greyscale: () => Color & any; clearer: (ratio: any) => Color & any; toJSON: () => any; } +>this : this greyscale: function () {return this;}, ->greyscale : () => Color & { negate: () => Color & any; lighten: (ratio: any) => Color & any; darken: (ratio: any) => Color & any; saturate: (ratio: any) => Color & any; desaturate: (ratio: any) => Color & any; whiten: (ratio: any) => Color & any; blacken: (ratio: any) => Color & any; greyscale: any; clearer: (ratio: any) => Color & any; toJSON: () => any; } ->function () {return this;} : () => Color & { negate: () => Color & any; lighten: (ratio: any) => Color & any; darken: (ratio: any) => Color & any; saturate: (ratio: any) => Color & any; desaturate: (ratio: any) => Color & any; whiten: (ratio: any) => Color & any; blacken: (ratio: any) => Color & any; greyscale: any; clearer: (ratio: any) => Color & any; toJSON: () => any; } ->this : Color & { negate: () => Color & any; lighten: (ratio: any) => Color & any; darken: (ratio: any) => Color & any; saturate: (ratio: any) => Color & any; desaturate: (ratio: any) => Color & any; whiten: (ratio: any) => Color & any; blacken: (ratio: any) => Color & any; greyscale: () => Color & any; clearer: (ratio: any) => Color & any; toJSON: () => any; } +>greyscale : () => this +>function () {return this;} : () => this +>this : this clearer: function (ratio) {return this;}, ->clearer : (ratio: any) => Color & { negate: () => Color & any; lighten: (ratio: any) => Color & any; darken: (ratio: any) => Color & any; saturate: (ratio: any) => Color & any; desaturate: (ratio: any) => Color & any; whiten: (ratio: any) => Color & any; blacken: (ratio: any) => Color & any; greyscale: () => Color & any; clearer: any; toJSON: () => any; } ->function (ratio) {return this;} : (ratio: any) => Color & { negate: () => Color & any; lighten: (ratio: any) => Color & any; darken: (ratio: any) => Color & any; saturate: (ratio: any) => Color & any; desaturate: (ratio: any) => Color & any; whiten: (ratio: any) => Color & any; blacken: (ratio: any) => Color & any; greyscale: () => Color & any; clearer: any; toJSON: () => any; } +>clearer : (ratio: any) => this +>function (ratio) {return this;} : (ratio: any) => this >ratio : any ->this : Color & { negate: () => Color & any; lighten: (ratio: any) => Color & any; darken: (ratio: any) => Color & any; saturate: (ratio: any) => Color & any; desaturate: (ratio: any) => Color & any; whiten: (ratio: any) => Color & any; blacken: (ratio: any) => Color & any; greyscale: () => Color & any; clearer: (ratio: any) => Color & any; toJSON: () => any; } +>this : this toJSON: function () {return this.rgb();}, >toJSON : () => any >function () {return this.rgb();} : () => any >this.rgb() : any >this.rgb : any ->this : Color & { negate: () => Color & any; lighten: (ratio: any) => Color & any; darken: (ratio: any) => Color & any; saturate: (ratio: any) => Color & any; desaturate: (ratio: any) => Color & any; whiten: (ratio: any) => Color & any; blacken: (ratio: any) => Color & any; greyscale: () => Color & any; clearer: (ratio: any) => Color & any; toJSON: () => any; } +>this : this >rgb : any }; diff --git a/tests/baselines/reference/jsdocFunctionType.types b/tests/baselines/reference/jsdocFunctionType.types index ebacf52ab17..b679c4326f8 100644 --- a/tests/baselines/reference/jsdocFunctionType.types +++ b/tests/baselines/reference/jsdocFunctionType.types @@ -93,7 +93,7 @@ function D(n) { this.length = n; >this.length = n : number >this.length : number ->this : D +>this : this >length : number >n : number } @@ -152,7 +152,7 @@ var E = function(n) { this.not_length_on_purpose = n; >this.not_length_on_purpose = n : number >this.not_length_on_purpose : number ->this : E +>this : this >not_length_on_purpose : number >n : number diff --git a/tests/baselines/reference/jsdocTemplateConstructorFunction.types b/tests/baselines/reference/jsdocTemplateConstructorFunction.types index 4c0237aedeb..6caba31540c 100644 --- a/tests/baselines/reference/jsdocTemplateConstructorFunction.types +++ b/tests/baselines/reference/jsdocTemplateConstructorFunction.types @@ -42,38 +42,38 @@ Zet.prototype.add = function(v, id) { this.u = v || this.t >this.u = v || this.t : T >this.u : T ->this : Zet +>this : this >u : T >v || this.t : T >v : T >this.t : T ->this : Zet +>this : this >t : T return id(this.u) >id(this.u) : T >id : (u: T) => T >this.u : T ->this : Zet +>this : this >u : T } var z = new Zet(1) ->z : typeof Zet ->new Zet(1) : typeof Zet +>z : Zet +>new Zet(1) : Zet >Zet : typeof Zet >1 : 1 z.t = 2 >z.t = 2 : 2 >z.t : number ->z : typeof Zet +>z : Zet >t : number >2 : 2 z.u = false >z.u = false : false >z.u : number ->z : typeof Zet +>z : Zet >u : number >false : false diff --git a/tests/baselines/reference/jsdocTemplateConstructorFunction2.errors.txt b/tests/baselines/reference/jsdocTemplateConstructorFunction2.errors.txt index d7222f11ee2..93355d60205 100644 --- a/tests/baselines/reference/jsdocTemplateConstructorFunction2.errors.txt +++ b/tests/baselines/reference/jsdocTemplateConstructorFunction2.errors.txt @@ -1,5 +1,5 @@ tests/cases/conformance/jsdoc/templateTagWithNestedTypeLiteral.js(21,1): error TS2322: Type 'false' is not assignable to type 'number'. -tests/cases/conformance/jsdoc/templateTagWithNestedTypeLiteral.js(26,15): error TS2304: Cannot find name 'T'. +tests/cases/conformance/jsdoc/templateTagWithNestedTypeLiteral.js(28,15): error TS2304: Cannot find name 'T'. ==== tests/cases/conformance/jsdoc/templateTagWithNestedTypeLiteral.js (2 errors) ==== @@ -26,6 +26,8 @@ tests/cases/conformance/jsdoc/templateTagWithNestedTypeLiteral.js(26,15): error z.u = false ~~~ !!! error TS2322: Type 'false' is not assignable to type 'number'. + /** @type {number} */ + let answer = z.add(3, { nested: 4 }) // lookup in typedef should not crash the compiler, even when the type is unknown /** diff --git a/tests/baselines/reference/jsdocTemplateConstructorFunction2.symbols b/tests/baselines/reference/jsdocTemplateConstructorFunction2.symbols index 073a59c283d..41211488656 100644 --- a/tests/baselines/reference/jsdocTemplateConstructorFunction2.symbols +++ b/tests/baselines/reference/jsdocTemplateConstructorFunction2.symbols @@ -54,6 +54,14 @@ z.u = false >z : Symbol(z, Decl(templateTagWithNestedTypeLiteral.js, 18, 3), Decl(templateTagWithNestedTypeLiteral.js, 18, 18), Decl(templateTagWithNestedTypeLiteral.js, 19, 7)) >u : Symbol(Zet.u, Decl(templateTagWithNestedTypeLiteral.js, 4, 17), Decl(templateTagWithNestedTypeLiteral.js, 14, 36)) +/** @type {number} */ +let answer = z.add(3, { nested: 4 }) +>answer : Symbol(answer, Decl(templateTagWithNestedTypeLiteral.js, 22, 3)) +>z.add : Symbol(Zet.add, Decl(templateTagWithNestedTypeLiteral.js, 8, 1)) +>z : Symbol(z, Decl(templateTagWithNestedTypeLiteral.js, 18, 3), Decl(templateTagWithNestedTypeLiteral.js, 18, 18), Decl(templateTagWithNestedTypeLiteral.js, 19, 7)) +>add : Symbol(Zet.add, Decl(templateTagWithNestedTypeLiteral.js, 8, 1)) +>nested : Symbol(nested, Decl(templateTagWithNestedTypeLiteral.js, 22, 23)) + // lookup in typedef should not crash the compiler, even when the type is unknown /** * @typedef {Object} A @@ -61,6 +69,6 @@ z.u = false */ /** @type {A} */ const options = { value: null }; ->options : Symbol(options, Decl(templateTagWithNestedTypeLiteral.js, 28, 5)) ->value : Symbol(value, Decl(templateTagWithNestedTypeLiteral.js, 28, 17)) +>options : Symbol(options, Decl(templateTagWithNestedTypeLiteral.js, 30, 5)) +>value : Symbol(value, Decl(templateTagWithNestedTypeLiteral.js, 30, 17)) diff --git a/tests/baselines/reference/jsdocTemplateConstructorFunction2.types b/tests/baselines/reference/jsdocTemplateConstructorFunction2.types index 91c820ce094..dc70e5282c3 100644 --- a/tests/baselines/reference/jsdocTemplateConstructorFunction2.types +++ b/tests/baselines/reference/jsdocTemplateConstructorFunction2.types @@ -39,7 +39,7 @@ Zet.prototype.add = function(v, o) { this.u = v || o.nested >this.u = v || o.nested : T >this.u : T ->this : Zet +>this : this >u : T >v || o.nested : T >v : T @@ -49,29 +49,41 @@ Zet.prototype.add = function(v, o) { return this.u >this.u : T ->this : Zet +>this : this >u : T } var z = new Zet(1) ->z : typeof Zet ->new Zet(1) : typeof Zet +>z : Zet +>new Zet(1) : Zet >Zet : typeof Zet >1 : 1 z.t = 2 >z.t = 2 : 2 >z.t : number ->z : typeof Zet +>z : Zet >t : number >2 : 2 z.u = false >z.u = false : false >z.u : number ->z : typeof Zet +>z : Zet >u : number >false : false +/** @type {number} */ +let answer = z.add(3, { nested: 4 }) +>answer : number +>z.add(3, { nested: 4 }) : number +>z.add : (v: number, o: { nested: number; }) => number +>z : Zet +>add : (v: number, o: { nested: number; }) => number +>3 : 3 +>{ nested: 4 } : { nested: number; } +>nested : number +>4 : 4 + // lookup in typedef should not crash the compiler, even when the type is unknown /** * @typedef {Object} A diff --git a/tests/baselines/reference/jsdocTemplateTag4.types b/tests/baselines/reference/jsdocTemplateTag4.types index 6df18d4b98a..ea4030290f6 100644 --- a/tests/baselines/reference/jsdocTemplateTag4.types +++ b/tests/baselines/reference/jsdocTemplateTag4.types @@ -12,7 +12,7 @@ function Multimap() { this._map = {}; >this._map = {} : {} >this._map : { [x: string]: V; } ->this : Multimap +>this : this >_map : { [x: string]: V; } >{} : {} @@ -35,7 +35,7 @@ Multimap.prototype.get = function (key) { return this._map[key + '']; >this._map[key + ''] : V >this._map : { [x: string]: V; } ->this : Multimap +>this : this >_map : { [x: string]: V; } >key + '' : string >key : K @@ -56,7 +56,7 @@ var Multimap2 = function() { this._map = {}; >this._map = {} : {} >this._map : { [x: string]: V; } ->this : Multimap2 +>this : this >_map : { [x: string]: V; } >{} : {} @@ -79,7 +79,7 @@ Multimap2.prototype.get = function (key) { return this._map[key + '']; >this._map[key + ''] : V >this._map : { [x: string]: V; } ->this : Multimap2 +>this : this >_map : { [x: string]: V; } >key + '' : string >key : K @@ -107,7 +107,7 @@ Ns.Multimap3 = function() { this._map = {}; >this._map = {} : {} >this._map : { [x: string]: V; } ->this : Multimap3 +>this : this >_map : { [x: string]: V; } >{} : {} @@ -132,7 +132,7 @@ Ns.Multimap3.prototype.get = function (key) { return this._map[key + '']; >this._map[key + ''] : V >this._map : { [x: string]: V; } ->this : Multimap3 +>this : this >_map : { [x: string]: V; } >key + '' : string >key : K diff --git a/tests/baselines/reference/jsdocTemplateTag5.symbols b/tests/baselines/reference/jsdocTemplateTag5.symbols index aa1b023f339..c7237194dfb 100644 --- a/tests/baselines/reference/jsdocTemplateTag5.symbols +++ b/tests/baselines/reference/jsdocTemplateTag5.symbols @@ -11,6 +11,7 @@ function Multimap() { /** @type {Object} TODO: Remove the prototype from the fresh object */ this._map = {}; >this._map : Symbol(Multimap._map, Decl(a.js, 6, 21)) +>this : Symbol(Multimap, Decl(a.js, 0, 0), Decl(a.js, 9, 2)) >_map : Symbol(Multimap._map, Decl(a.js, 6, 21)) }; @@ -30,6 +31,7 @@ Multimap.prototype = { return this._map[key + '']; >this._map : Symbol(Multimap._map, Decl(a.js, 6, 21)) +>this : Symbol(Multimap, Decl(a.js, 0, 0), Decl(a.js, 9, 2)) >_map : Symbol(Multimap._map, Decl(a.js, 6, 21)) >key : Symbol(key, Decl(a.js, 16, 8)) } @@ -47,6 +49,7 @@ var Multimap2 = function() { /** @type {Object} TODO: Remove the prototype from the fresh object */ this._map = {}; >this._map : Symbol(Multimap2._map, Decl(a.js, 27, 28)) +>this : Symbol(Multimap2, Decl(a.js, 27, 15)) >_map : Symbol(Multimap2._map, Decl(a.js, 27, 28)) }; @@ -66,6 +69,7 @@ Multimap2.prototype = { return this._map[key + '']; >this._map : Symbol(Multimap2._map, Decl(a.js, 27, 28)) +>this : Symbol(Multimap2, Decl(a.js, 27, 15)) >_map : Symbol(Multimap2._map, Decl(a.js, 27, 28)) >key : Symbol(key, Decl(a.js, 37, 18)) } @@ -88,6 +92,7 @@ Ns.Multimap3 = function() { /** @type {Object} TODO: Remove the prototype from the fresh object */ this._map = {}; >this._map : Symbol(Multimap3._map, Decl(a.js, 49, 27)) +>this : Symbol(Multimap3, Decl(a.js, 49, 14)) >_map : Symbol(Multimap3._map, Decl(a.js, 49, 27)) }; @@ -109,6 +114,7 @@ Ns.Multimap3.prototype = { return this._map[key + '']; >this._map : Symbol(Multimap3._map, Decl(a.js, 49, 27)) +>this : Symbol(Multimap3, Decl(a.js, 49, 14)) >_map : Symbol(Multimap3._map, Decl(a.js, 49, 27)) >key : Symbol(key, Decl(a.js, 59, 8)) } diff --git a/tests/baselines/reference/jsdocTemplateTag5.types b/tests/baselines/reference/jsdocTemplateTag5.types index 1195b372e18..f009c708731 100644 --- a/tests/baselines/reference/jsdocTemplateTag5.types +++ b/tests/baselines/reference/jsdocTemplateTag5.types @@ -12,7 +12,7 @@ function Multimap() { this._map = {}; >this._map = {} : {} >this._map : { [x: string]: V; } ->this : Multimap & { get(key: K): V; } +>this : this >_map : { [x: string]: V; } >{} : {} @@ -36,7 +36,7 @@ Multimap.prototype = { return this._map[key + '']; >this._map[key + ''] : V >this._map : { [x: string]: V; } ->this : Multimap & { get(key: K): V; } +>this : this >_map : { [x: string]: V; } >key + '' : string >key : K @@ -58,7 +58,7 @@ var Multimap2 = function() { this._map = {}; >this._map = {} : {} >this._map : { [x: string]: V; } ->this : Multimap2 & { get: (key: K) => V; } +>this : this >_map : { [x: string]: V; } >{} : {} @@ -83,7 +83,7 @@ Multimap2.prototype = { return this._map[key + '']; >this._map[key + ''] : V >this._map : { [x: string]: V; } ->this : Multimap2 & { get: (key: K) => V; } +>this : this >_map : { [x: string]: V; } >key + '' : string >key : K @@ -112,7 +112,7 @@ Ns.Multimap3 = function() { this._map = {}; >this._map = {} : {} >this._map : { [x: string]: V; } ->this : Multimap3 & { get(key: K): V; } +>this : this >_map : { [x: string]: V; } >{} : {} @@ -138,7 +138,7 @@ Ns.Multimap3.prototype = { return this._map[key + '']; >this._map[key + ''] : V >this._map : { [x: string]: V; } ->this : Multimap3 & { get(key: K): V; } +>this : this >_map : { [x: string]: V; } >key + '' : string >key : K diff --git a/tests/baselines/reference/jsdocTypeFromChainedAssignment.types b/tests/baselines/reference/jsdocTypeFromChainedAssignment.types index 2cb44d2a7ba..974ba2b1cdd 100644 --- a/tests/baselines/reference/jsdocTypeFromChainedAssignment.types +++ b/tests/baselines/reference/jsdocTypeFromChainedAssignment.types @@ -43,7 +43,7 @@ A.prototype.y = A.prototype.z = function f(n) { >n + this.x : number >n : number >this.x : number ->this : A +>this : this >x : number } /** @param {number} m */ diff --git a/tests/baselines/reference/methodsReturningThis.types b/tests/baselines/reference/methodsReturningThis.types index b7acb814822..544139497e0 100644 --- a/tests/baselines/reference/methodsReturningThis.types +++ b/tests/baselines/reference/methodsReturningThis.types @@ -14,80 +14,80 @@ Class.prototype.containsError = function () { return this.notPresent; }; >containsError : any >function () { return this.notPresent; } : () => any >this.notPresent : error ->this : Class +>this : this >notPresent : any // lots of methods that return this, which caused out-of-memory in #9527 Class.prototype.m1 = function (a, b, c, d, tx, ty) { return this; }; ->Class.prototype.m1 = function (a, b, c, d, tx, ty) { return this; } : (a: any, b: any, c: any, d: any, tx: any, ty: any) => Class +>Class.prototype.m1 = function (a, b, c, d, tx, ty) { return this; } : (a: any, b: any, c: any, d: any, tx: any, ty: any) => this >Class.prototype.m1 : any >Class.prototype : any >Class : typeof Class >prototype : any >m1 : any ->function (a, b, c, d, tx, ty) { return this; } : (a: any, b: any, c: any, d: any, tx: any, ty: any) => Class +>function (a, b, c, d, tx, ty) { return this; } : (a: any, b: any, c: any, d: any, tx: any, ty: any) => this >a : any >b : any >c : any >d : any >tx : any >ty : any ->this : Class +>this : this Class.prototype.m2 = function (x, y) { return this; }; ->Class.prototype.m2 = function (x, y) { return this; } : (x: any, y: any) => Class +>Class.prototype.m2 = function (x, y) { return this; } : (x: any, y: any) => this >Class.prototype.m2 : any >Class.prototype : any >Class : typeof Class >prototype : any >m2 : any ->function (x, y) { return this; } : (x: any, y: any) => Class +>function (x, y) { return this; } : (x: any, y: any) => this >x : any >y : any ->this : Class +>this : this Class.prototype.m3 = function (x, y) { return this; }; ->Class.prototype.m3 = function (x, y) { return this; } : (x: any, y: any) => Class +>Class.prototype.m3 = function (x, y) { return this; } : (x: any, y: any) => this >Class.prototype.m3 : any >Class.prototype : any >Class : typeof Class >prototype : any >m3 : any ->function (x, y) { return this; } : (x: any, y: any) => Class +>function (x, y) { return this; } : (x: any, y: any) => this >x : any >y : any ->this : Class +>this : this Class.prototype.m4 = function (angle) { return this; }; ->Class.prototype.m4 = function (angle) { return this; } : (angle: any) => Class +>Class.prototype.m4 = function (angle) { return this; } : (angle: any) => this >Class.prototype.m4 : any >Class.prototype : any >Class : typeof Class >prototype : any >m4 : any ->function (angle) { return this; } : (angle: any) => Class +>function (angle) { return this; } : (angle: any) => this >angle : any ->this : Class +>this : this Class.prototype.m5 = function (matrix) { return this; }; ->Class.prototype.m5 = function (matrix) { return this; } : (matrix: any) => Class +>Class.prototype.m5 = function (matrix) { return this; } : (matrix: any) => this >Class.prototype.m5 : any >Class.prototype : any >Class : typeof Class >prototype : any >m5 : any ->function (matrix) { return this; } : (matrix: any) => Class +>function (matrix) { return this; } : (matrix: any) => this >matrix : any ->this : Class +>this : this Class.prototype.m6 = function (x, y, pivotX, pivotY, scaleX, scaleY, rotation, skewX, skewY) { return this; }; ->Class.prototype.m6 = function (x, y, pivotX, pivotY, scaleX, scaleY, rotation, skewX, skewY) { return this; } : (x: any, y: any, pivotX: any, pivotY: any, scaleX: any, scaleY: any, rotation: any, skewX: any, skewY: any) => Class +>Class.prototype.m6 = function (x, y, pivotX, pivotY, scaleX, scaleY, rotation, skewX, skewY) { return this; } : (x: any, y: any, pivotX: any, pivotY: any, scaleX: any, scaleY: any, rotation: any, skewX: any, skewY: any) => this >Class.prototype.m6 : any >Class.prototype : any >Class : typeof Class >prototype : any >m6 : any ->function (x, y, pivotX, pivotY, scaleX, scaleY, rotation, skewX, skewY) { return this; } : (x: any, y: any, pivotX: any, pivotY: any, scaleX: any, scaleY: any, rotation: any, skewX: any, skewY: any) => Class +>function (x, y, pivotX, pivotY, scaleX, scaleY, rotation, skewX, skewY) { return this; } : (x: any, y: any, pivotX: any, pivotY: any, scaleX: any, scaleY: any, rotation: any, skewX: any, skewY: any) => this >x : any >y : any >pivotX : any @@ -97,37 +97,37 @@ Class.prototype.m6 = function (x, y, pivotX, pivotY, scaleX, scaleY, rotation, s >rotation : any >skewX : any >skewY : any ->this : Class +>this : this Class.prototype.m7 = function(matrix) { return this; }; ->Class.prototype.m7 = function(matrix) { return this; } : (matrix: any) => Class +>Class.prototype.m7 = function(matrix) { return this; } : (matrix: any) => this >Class.prototype.m7 : any >Class.prototype : any >Class : typeof Class >prototype : any >m7 : any ->function(matrix) { return this; } : (matrix: any) => Class +>function(matrix) { return this; } : (matrix: any) => this >matrix : any ->this : Class +>this : this Class.prototype.m8 = function() { return this; }; ->Class.prototype.m8 = function() { return this; } : () => Class +>Class.prototype.m8 = function() { return this; } : () => this >Class.prototype.m8 : any >Class.prototype : any >Class : typeof Class >prototype : any >m8 : any ->function() { return this; } : () => Class ->this : Class +>function() { return this; } : () => this +>this : this Class.prototype.m9 = function () { return this; }; ->Class.prototype.m9 = function () { return this; } : () => Class +>Class.prototype.m9 = function () { return this; } : () => this >Class.prototype.m9 : any >Class.prototype : any >Class : typeof Class >prototype : any >m9 : any ->function () { return this; } : () => Class ->this : Class +>function () { return this; } : () => this +>this : this diff --git a/tests/baselines/reference/moduleExportAliasImported.types b/tests/baselines/reference/moduleExportAliasImported.types index 9691acfab22..b4d6f4d9031 100644 --- a/tests/baselines/reference/moduleExportAliasImported.types +++ b/tests/baselines/reference/moduleExportAliasImported.types @@ -18,6 +18,6 @@ module.exports = alias === tests/cases/conformance/salsa/importer.js === import('./bug28014') ->import('./bug28014') : Promise<() => void> +>import('./bug28014') : Promise<{ (): void; version: number; }> >'./bug28014' : "./bug28014" diff --git a/tests/baselines/reference/multipleDeclarations.types b/tests/baselines/reference/multipleDeclarations.types index d006f4f6512..445d737019e 100644 --- a/tests/baselines/reference/multipleDeclarations.types +++ b/tests/baselines/reference/multipleDeclarations.types @@ -21,7 +21,7 @@ C.prototype.m = function() { this.nothing(); >this.nothing() : error >this.nothing : error ->this : C +>this : this >nothing : any } class X { diff --git a/tests/baselines/reference/propertiesOfGenericConstructorFunctions.symbols b/tests/baselines/reference/propertiesOfGenericConstructorFunctions.symbols new file mode 100644 index 00000000000..48606c4b15c --- /dev/null +++ b/tests/baselines/reference/propertiesOfGenericConstructorFunctions.symbols @@ -0,0 +1,139 @@ +=== tests/cases/conformance/salsa/propertiesOfGenericConstructorFunctions.js === +/** + * @template {string} K + * @template V + * @param {string} ik + * @param {V} iv + */ +function Multimap(ik, iv) { +>Multimap : Symbol(Multimap, Decl(propertiesOfGenericConstructorFunctions.js, 0, 0)) +>ik : Symbol(ik, Decl(propertiesOfGenericConstructorFunctions.js, 6, 18)) +>iv : Symbol(iv, Decl(propertiesOfGenericConstructorFunctions.js, 6, 21)) + + /** @type {{ [s: string]: V }} */ + this._map = {}; +>_map : Symbol(Multimap._map, Decl(propertiesOfGenericConstructorFunctions.js, 6, 27)) + + // without type annotation + this._map2 = { [ik]: iv }; +>_map2 : Symbol(Multimap._map2, Decl(propertiesOfGenericConstructorFunctions.js, 8, 19)) +>[ik] : Symbol([ik], Decl(propertiesOfGenericConstructorFunctions.js, 10, 18)) +>ik : Symbol(ik, Decl(propertiesOfGenericConstructorFunctions.js, 6, 18)) +>iv : Symbol(iv, Decl(propertiesOfGenericConstructorFunctions.js, 6, 21)) + +}; + +/** @type {Multimap<"a" | "b", number>} with type annotation */ +const map = new Multimap("a", 1); +>map : Symbol(map, Decl(propertiesOfGenericConstructorFunctions.js, 14, 5)) +>Multimap : Symbol(Multimap, Decl(propertiesOfGenericConstructorFunctions.js, 0, 0)) + +// without type annotation +const map2 = new Multimap("m", 2); +>map2 : Symbol(map2, Decl(propertiesOfGenericConstructorFunctions.js, 16, 5)) +>Multimap : Symbol(Multimap, Decl(propertiesOfGenericConstructorFunctions.js, 0, 0)) + +/** @type {number} */ +var n = map._map['hi'] +>n : Symbol(n, Decl(propertiesOfGenericConstructorFunctions.js, 19, 3), Decl(propertiesOfGenericConstructorFunctions.js, 21, 3), Decl(propertiesOfGenericConstructorFunctions.js, 23, 3), Decl(propertiesOfGenericConstructorFunctions.js, 25, 3), Decl(propertiesOfGenericConstructorFunctions.js, 43, 3) ... and 3 more) +>map._map : Symbol(Multimap._map, Decl(propertiesOfGenericConstructorFunctions.js, 6, 27)) +>map : Symbol(map, Decl(propertiesOfGenericConstructorFunctions.js, 14, 5)) +>_map : Symbol(Multimap._map, Decl(propertiesOfGenericConstructorFunctions.js, 6, 27)) + +/** @type {number} */ +var n = map._map2['hi'] +>n : Symbol(n, Decl(propertiesOfGenericConstructorFunctions.js, 19, 3), Decl(propertiesOfGenericConstructorFunctions.js, 21, 3), Decl(propertiesOfGenericConstructorFunctions.js, 23, 3), Decl(propertiesOfGenericConstructorFunctions.js, 25, 3), Decl(propertiesOfGenericConstructorFunctions.js, 43, 3) ... and 3 more) +>map._map2 : Symbol(Multimap._map2, Decl(propertiesOfGenericConstructorFunctions.js, 8, 19)) +>map : Symbol(map, Decl(propertiesOfGenericConstructorFunctions.js, 14, 5)) +>_map2 : Symbol(Multimap._map2, Decl(propertiesOfGenericConstructorFunctions.js, 8, 19)) + +/** @type {number} */ +var n = map2._map['hi'] +>n : Symbol(n, Decl(propertiesOfGenericConstructorFunctions.js, 19, 3), Decl(propertiesOfGenericConstructorFunctions.js, 21, 3), Decl(propertiesOfGenericConstructorFunctions.js, 23, 3), Decl(propertiesOfGenericConstructorFunctions.js, 25, 3), Decl(propertiesOfGenericConstructorFunctions.js, 43, 3) ... and 3 more) +>map2._map : Symbol(Multimap._map, Decl(propertiesOfGenericConstructorFunctions.js, 6, 27)) +>map2 : Symbol(map2, Decl(propertiesOfGenericConstructorFunctions.js, 16, 5)) +>_map : Symbol(Multimap._map, Decl(propertiesOfGenericConstructorFunctions.js, 6, 27)) + +/** @type {number} */ +var n = map._map2['hi'] +>n : Symbol(n, Decl(propertiesOfGenericConstructorFunctions.js, 19, 3), Decl(propertiesOfGenericConstructorFunctions.js, 21, 3), Decl(propertiesOfGenericConstructorFunctions.js, 23, 3), Decl(propertiesOfGenericConstructorFunctions.js, 25, 3), Decl(propertiesOfGenericConstructorFunctions.js, 43, 3) ... and 3 more) +>map._map2 : Symbol(Multimap._map2, Decl(propertiesOfGenericConstructorFunctions.js, 8, 19)) +>map : Symbol(map, Decl(propertiesOfGenericConstructorFunctions.js, 14, 5)) +>_map2 : Symbol(Multimap._map2, Decl(propertiesOfGenericConstructorFunctions.js, 8, 19)) + +/** + * @class + * @template T + * @param {T} t + */ +function Cp(t) { +>Cp : Symbol(Cp, Decl(propertiesOfGenericConstructorFunctions.js, 25, 23), Decl(propertiesOfGenericConstructorFunctions.js, 35, 1)) +>t : Symbol(t, Decl(propertiesOfGenericConstructorFunctions.js, 32, 12)) + + this.x = 1 +>this.x : Symbol(Cp.x, Decl(propertiesOfGenericConstructorFunctions.js, 32, 16)) +>this : Symbol(Cp, Decl(propertiesOfGenericConstructorFunctions.js, 25, 23), Decl(propertiesOfGenericConstructorFunctions.js, 35, 1)) +>x : Symbol(Cp.x, Decl(propertiesOfGenericConstructorFunctions.js, 32, 16)) + + this.y = t +>this.y : Symbol(Cp.y, Decl(propertiesOfGenericConstructorFunctions.js, 33, 14)) +>this : Symbol(Cp, Decl(propertiesOfGenericConstructorFunctions.js, 25, 23), Decl(propertiesOfGenericConstructorFunctions.js, 35, 1)) +>y : Symbol(Cp.y, Decl(propertiesOfGenericConstructorFunctions.js, 33, 14)) +>t : Symbol(t, Decl(propertiesOfGenericConstructorFunctions.js, 32, 12)) +} +Cp.prototype = { +>Cp.prototype : Symbol(Cp.prototype, Decl(propertiesOfGenericConstructorFunctions.js, 35, 1)) +>Cp : Symbol(Cp, Decl(propertiesOfGenericConstructorFunctions.js, 25, 23), Decl(propertiesOfGenericConstructorFunctions.js, 35, 1)) +>prototype : Symbol(Cp.prototype, Decl(propertiesOfGenericConstructorFunctions.js, 35, 1)) + + m1() { return this.x }, +>m1 : Symbol(m1, Decl(propertiesOfGenericConstructorFunctions.js, 36, 16)) +>this.x : Symbol(Cp.x, Decl(propertiesOfGenericConstructorFunctions.js, 32, 16)) +>this : Symbol(Cp, Decl(propertiesOfGenericConstructorFunctions.js, 25, 23), Decl(propertiesOfGenericConstructorFunctions.js, 35, 1)) +>x : Symbol(Cp.x, Decl(propertiesOfGenericConstructorFunctions.js, 32, 16)) + + m2() { this.z = this.x + 1; return this.y } +>m2 : Symbol(m2, Decl(propertiesOfGenericConstructorFunctions.js, 37, 27)) +>this.z : Symbol(z, Decl(propertiesOfGenericConstructorFunctions.js, 38, 10)) +>this : Symbol(Cp, Decl(propertiesOfGenericConstructorFunctions.js, 25, 23), Decl(propertiesOfGenericConstructorFunctions.js, 35, 1)) +>z : Symbol(z, Decl(propertiesOfGenericConstructorFunctions.js, 38, 10)) +>this.x : Symbol(Cp.x, Decl(propertiesOfGenericConstructorFunctions.js, 32, 16)) +>this : Symbol(Cp, Decl(propertiesOfGenericConstructorFunctions.js, 25, 23), Decl(propertiesOfGenericConstructorFunctions.js, 35, 1)) +>x : Symbol(Cp.x, Decl(propertiesOfGenericConstructorFunctions.js, 32, 16)) +>this.y : Symbol(Cp.y, Decl(propertiesOfGenericConstructorFunctions.js, 33, 14)) +>this : Symbol(Cp, Decl(propertiesOfGenericConstructorFunctions.js, 25, 23), Decl(propertiesOfGenericConstructorFunctions.js, 35, 1)) +>y : Symbol(Cp.y, Decl(propertiesOfGenericConstructorFunctions.js, 33, 14)) +} +var cp = new Cp(1) +>cp : Symbol(cp, Decl(propertiesOfGenericConstructorFunctions.js, 40, 3)) +>Cp : Symbol(Cp, Decl(propertiesOfGenericConstructorFunctions.js, 25, 23), Decl(propertiesOfGenericConstructorFunctions.js, 35, 1)) + +/** @type {number} */ +var n = cp.x +>n : Symbol(n, Decl(propertiesOfGenericConstructorFunctions.js, 19, 3), Decl(propertiesOfGenericConstructorFunctions.js, 21, 3), Decl(propertiesOfGenericConstructorFunctions.js, 23, 3), Decl(propertiesOfGenericConstructorFunctions.js, 25, 3), Decl(propertiesOfGenericConstructorFunctions.js, 43, 3) ... and 3 more) +>cp.x : Symbol(Cp.x, Decl(propertiesOfGenericConstructorFunctions.js, 32, 16)) +>cp : Symbol(cp, Decl(propertiesOfGenericConstructorFunctions.js, 40, 3)) +>x : Symbol(Cp.x, Decl(propertiesOfGenericConstructorFunctions.js, 32, 16)) + +/** @type {number} */ +var n = cp.y +>n : Symbol(n, Decl(propertiesOfGenericConstructorFunctions.js, 19, 3), Decl(propertiesOfGenericConstructorFunctions.js, 21, 3), Decl(propertiesOfGenericConstructorFunctions.js, 23, 3), Decl(propertiesOfGenericConstructorFunctions.js, 25, 3), Decl(propertiesOfGenericConstructorFunctions.js, 43, 3) ... and 3 more) +>cp.y : Symbol(Cp.y, Decl(propertiesOfGenericConstructorFunctions.js, 33, 14)) +>cp : Symbol(cp, Decl(propertiesOfGenericConstructorFunctions.js, 40, 3)) +>y : Symbol(Cp.y, Decl(propertiesOfGenericConstructorFunctions.js, 33, 14)) + +/** @type {number} */ +var n = cp.m1() +>n : Symbol(n, Decl(propertiesOfGenericConstructorFunctions.js, 19, 3), Decl(propertiesOfGenericConstructorFunctions.js, 21, 3), Decl(propertiesOfGenericConstructorFunctions.js, 23, 3), Decl(propertiesOfGenericConstructorFunctions.js, 25, 3), Decl(propertiesOfGenericConstructorFunctions.js, 43, 3) ... and 3 more) +>cp.m1 : Symbol(m1, Decl(propertiesOfGenericConstructorFunctions.js, 36, 16)) +>cp : Symbol(cp, Decl(propertiesOfGenericConstructorFunctions.js, 40, 3)) +>m1 : Symbol(m1, Decl(propertiesOfGenericConstructorFunctions.js, 36, 16)) + +/** @type {number} */ +var n = cp.m2() +>n : Symbol(n, Decl(propertiesOfGenericConstructorFunctions.js, 19, 3), Decl(propertiesOfGenericConstructorFunctions.js, 21, 3), Decl(propertiesOfGenericConstructorFunctions.js, 23, 3), Decl(propertiesOfGenericConstructorFunctions.js, 25, 3), Decl(propertiesOfGenericConstructorFunctions.js, 43, 3) ... and 3 more) +>cp.m2 : Symbol(m2, Decl(propertiesOfGenericConstructorFunctions.js, 37, 27)) +>cp : Symbol(cp, Decl(propertiesOfGenericConstructorFunctions.js, 40, 3)) +>m2 : Symbol(m2, Decl(propertiesOfGenericConstructorFunctions.js, 37, 27)) + + diff --git a/tests/baselines/reference/propertiesOfGenericConstructorFunctions.types b/tests/baselines/reference/propertiesOfGenericConstructorFunctions.types new file mode 100644 index 00000000000..71ef32425ab --- /dev/null +++ b/tests/baselines/reference/propertiesOfGenericConstructorFunctions.types @@ -0,0 +1,173 @@ +=== tests/cases/conformance/salsa/propertiesOfGenericConstructorFunctions.js === +/** + * @template {string} K + * @template V + * @param {string} ik + * @param {V} iv + */ +function Multimap(ik, iv) { +>Multimap : typeof Multimap +>ik : string +>iv : V + + /** @type {{ [s: string]: V }} */ + this._map = {}; +>this._map = {} : {} +>this._map : any +>this : any +>_map : any +>{} : {} + + // without type annotation + this._map2 = { [ik]: iv }; +>this._map2 = { [ik]: iv } : { [x: string]: V; } +>this._map2 : any +>this : any +>_map2 : any +>{ [ik]: iv } : { [x: string]: V; } +>[ik] : V +>ik : string +>iv : V + +}; + +/** @type {Multimap<"a" | "b", number>} with type annotation */ +const map = new Multimap("a", 1); +>map : Multimap<"a" | "b", number> +>new Multimap("a", 1) : Multimap<"a" | "b", number> +>Multimap : typeof Multimap +>"a" : "a" +>1 : 1 + +// without type annotation +const map2 = new Multimap("m", 2); +>map2 : Multimap +>new Multimap("m", 2) : Multimap +>Multimap : typeof Multimap +>"m" : "m" +>2 : 2 + +/** @type {number} */ +var n = map._map['hi'] +>n : number +>map._map['hi'] : number +>map._map : { [s: string]: number; } +>map : Multimap<"a" | "b", number> +>_map : { [s: string]: number; } +>'hi' : "hi" + +/** @type {number} */ +var n = map._map2['hi'] +>n : number +>map._map2['hi'] : number +>map._map2 : { [x: string]: number; } +>map : Multimap<"a" | "b", number> +>_map2 : { [x: string]: number; } +>'hi' : "hi" + +/** @type {number} */ +var n = map2._map['hi'] +>n : number +>map2._map['hi'] : number +>map2._map : { [s: string]: number; } +>map2 : Multimap +>_map : { [s: string]: number; } +>'hi' : "hi" + +/** @type {number} */ +var n = map._map2['hi'] +>n : number +>map._map2['hi'] : number +>map._map2 : { [x: string]: number; } +>map : Multimap<"a" | "b", number> +>_map2 : { [x: string]: number; } +>'hi' : "hi" + +/** + * @class + * @template T + * @param {T} t + */ +function Cp(t) { +>Cp : typeof Cp +>t : T + + this.x = 1 +>this.x = 1 : 1 +>this.x : number +>this : this +>x : number +>1 : 1 + + this.y = t +>this.y = t : T +>this.y : T +>this : this +>y : T +>t : T +} +Cp.prototype = { +>Cp.prototype = { m1() { return this.x }, m2() { this.z = this.x + 1; return this.y }} : { m1(): number; m2(): T; } +>Cp.prototype : { m1(): number; m2(): T; } +>Cp : typeof Cp +>prototype : { m1(): number; m2(): T; } +>{ m1() { return this.x }, m2() { this.z = this.x + 1; return this.y }} : { m1(): number; m2(): T; } + + m1() { return this.x }, +>m1 : () => number +>this.x : number +>this : this +>x : number + + m2() { this.z = this.x + 1; return this.y } +>m2 : () => T +>this.z = this.x + 1 : number +>this.z : number +>this : this +>z : number +>this.x + 1 : number +>this.x : number +>this : this +>x : number +>1 : 1 +>this.y : T +>this : this +>y : T +} +var cp = new Cp(1) +>cp : Cp +>new Cp(1) : Cp +>Cp : typeof Cp +>1 : 1 + +/** @type {number} */ +var n = cp.x +>n : number +>cp.x : number +>cp : Cp +>x : number + +/** @type {number} */ +var n = cp.y +>n : number +>cp.y : number +>cp : Cp +>y : number + +/** @type {number} */ +var n = cp.m1() +>n : number +>cp.m1() : number +>cp.m1 : () => number +>cp : Cp +>m1 : () => number + +/** @type {number} */ +var n = cp.m2() +>n : number +>cp.m2() : number +>cp.m2 : () => number +>cp : Cp +>m2 : () => number + + diff --git a/tests/baselines/reference/prototypePropertyAssignmentMergeAcrossFiles.symbols b/tests/baselines/reference/prototypePropertyAssignmentMergeAcrossFiles.symbols new file mode 100644 index 00000000000..087d83cb6b3 --- /dev/null +++ b/tests/baselines/reference/prototypePropertyAssignmentMergeAcrossFiles.symbols @@ -0,0 +1,17 @@ +=== tests/cases/conformance/salsa/prototypePropertyAssignmentMergeAcrossFiles.js === +function C() { +>C : Symbol(C, Decl(prototypePropertyAssignmentMergeAcrossFiles.js, 0, 0)) + + this.a = 1 +>a : Symbol(C.a, Decl(prototypePropertyAssignmentMergeAcrossFiles.js, 0, 14)) +} + +=== tests/cases/conformance/salsa/other.js === +C.prototype.foo = function() { return this.a } +>C.prototype : Symbol(Function.prototype, Decl(lib.es5.d.ts, --, --)) +>C : Symbol(C, Decl(prototypePropertyAssignmentMergeAcrossFiles.js, 0, 0)) +>prototype : Symbol(Function.prototype, Decl(lib.es5.d.ts, --, --)) +>this.a : Symbol(C.a, Decl(prototypePropertyAssignmentMergeAcrossFiles.js, 0, 14)) +>this : Symbol(C, Decl(prototypePropertyAssignmentMergeAcrossFiles.js, 0, 0)) +>a : Symbol(C.a, Decl(prototypePropertyAssignmentMergeAcrossFiles.js, 0, 14)) + diff --git a/tests/baselines/reference/prototypePropertyAssignmentMergeAcrossFiles.types b/tests/baselines/reference/prototypePropertyAssignmentMergeAcrossFiles.types new file mode 100644 index 00000000000..8e399f618b9 --- /dev/null +++ b/tests/baselines/reference/prototypePropertyAssignmentMergeAcrossFiles.types @@ -0,0 +1,25 @@ +=== tests/cases/conformance/salsa/prototypePropertyAssignmentMergeAcrossFiles.js === +function C() { +>C : typeof C + + this.a = 1 +>this.a = 1 : 1 +>this.a : any +>this : any +>a : any +>1 : 1 +} + +=== tests/cases/conformance/salsa/other.js === +C.prototype.foo = function() { return this.a } +>C.prototype.foo = function() { return this.a } : () => number +>C.prototype.foo : any +>C.prototype : any +>C : typeof C +>prototype : any +>foo : any +>function() { return this.a } : () => number +>this.a : number +>this : this +>a : number + diff --git a/tests/baselines/reference/signaturesUseJSDocForOptionalParameters.types b/tests/baselines/reference/signaturesUseJSDocForOptionalParameters.types index 00cebcb574b..d1bdb0611bc 100644 --- a/tests/baselines/reference/signaturesUseJSDocForOptionalParameters.types +++ b/tests/baselines/reference/signaturesUseJSDocForOptionalParameters.types @@ -26,7 +26,7 @@ MyClass.prototype.optionalParam = function(required, notRequired) { >notRequired : string return this; ->this : MyClass +>this : this }; let pInst = new MyClass(); diff --git a/tests/baselines/reference/thisTypeOfConstructorFunctions.symbols b/tests/baselines/reference/thisTypeOfConstructorFunctions.symbols new file mode 100644 index 00000000000..637ad4f1e41 --- /dev/null +++ b/tests/baselines/reference/thisTypeOfConstructorFunctions.symbols @@ -0,0 +1,118 @@ +=== tests/cases/conformance/salsa/thisTypeOfConstructorFunctions.js === +/** + * @class + * @template T + * @param {T} t + */ +function Cp(t) { +>Cp : Symbol(Cp, Decl(thisTypeOfConstructorFunctions.js, 0, 0), Decl(thisTypeOfConstructorFunctions.js, 11, 1)) +>t : Symbol(t, Decl(thisTypeOfConstructorFunctions.js, 5, 12)) + + /** @type {this} */ + this.dit = this +>this.dit : Symbol(Cp.dit, Decl(thisTypeOfConstructorFunctions.js, 5, 16)) +>this : Symbol(Cp, Decl(thisTypeOfConstructorFunctions.js, 0, 0), Decl(thisTypeOfConstructorFunctions.js, 11, 1)) +>dit : Symbol(Cp.dit, Decl(thisTypeOfConstructorFunctions.js, 5, 16)) +>this : Symbol(Cp, Decl(thisTypeOfConstructorFunctions.js, 0, 0), Decl(thisTypeOfConstructorFunctions.js, 11, 1)) + + this.y = t +>this.y : Symbol(Cp.y, Decl(thisTypeOfConstructorFunctions.js, 7, 19)) +>this : Symbol(Cp, Decl(thisTypeOfConstructorFunctions.js, 0, 0), Decl(thisTypeOfConstructorFunctions.js, 11, 1)) +>y : Symbol(Cp.y, Decl(thisTypeOfConstructorFunctions.js, 7, 19)) +>t : Symbol(t, Decl(thisTypeOfConstructorFunctions.js, 5, 12)) + + /** @return {this} */ + this.m3 = () => this +>this.m3 : Symbol(Cp.m3, Decl(thisTypeOfConstructorFunctions.js, 8, 14)) +>this : Symbol(Cp, Decl(thisTypeOfConstructorFunctions.js, 0, 0), Decl(thisTypeOfConstructorFunctions.js, 11, 1)) +>m3 : Symbol(Cp.m3, Decl(thisTypeOfConstructorFunctions.js, 8, 14)) +>this : Symbol(Cp, Decl(thisTypeOfConstructorFunctions.js, 0, 0), Decl(thisTypeOfConstructorFunctions.js, 11, 1)) +} + +Cp.prototype = { +>Cp.prototype : Symbol(Cp.prototype, Decl(thisTypeOfConstructorFunctions.js, 11, 1)) +>Cp : Symbol(Cp, Decl(thisTypeOfConstructorFunctions.js, 0, 0), Decl(thisTypeOfConstructorFunctions.js, 11, 1)) +>prototype : Symbol(Cp.prototype, Decl(thisTypeOfConstructorFunctions.js, 11, 1)) + + /** @return {this} */ + m4() { +>m4 : Symbol(m4, Decl(thisTypeOfConstructorFunctions.js, 13, 16)) + + this.z = this.y; return this +>this.z : Symbol(z, Decl(thisTypeOfConstructorFunctions.js, 15, 10)) +>this : Symbol(Cp, Decl(thisTypeOfConstructorFunctions.js, 0, 0), Decl(thisTypeOfConstructorFunctions.js, 11, 1)) +>z : Symbol(z, Decl(thisTypeOfConstructorFunctions.js, 15, 10)) +>this.y : Symbol(Cp.y, Decl(thisTypeOfConstructorFunctions.js, 7, 19)) +>this : Symbol(Cp, Decl(thisTypeOfConstructorFunctions.js, 0, 0), Decl(thisTypeOfConstructorFunctions.js, 11, 1)) +>y : Symbol(Cp.y, Decl(thisTypeOfConstructorFunctions.js, 7, 19)) +>this : Symbol(Cp, Decl(thisTypeOfConstructorFunctions.js, 0, 0), Decl(thisTypeOfConstructorFunctions.js, 11, 1)) + } +} + +/** + * @class + * @template T + * @param {T} t + */ +function Cpp(t) { +>Cpp : Symbol(Cpp, Decl(thisTypeOfConstructorFunctions.js, 18, 1)) +>t : Symbol(t, Decl(thisTypeOfConstructorFunctions.js, 25, 13)) + + this.y = t +>this.y : Symbol(Cpp.y, Decl(thisTypeOfConstructorFunctions.js, 25, 17)) +>this : Symbol(Cpp, Decl(thisTypeOfConstructorFunctions.js, 18, 1)) +>y : Symbol(Cpp.y, Decl(thisTypeOfConstructorFunctions.js, 25, 17)) +>t : Symbol(t, Decl(thisTypeOfConstructorFunctions.js, 25, 13)) +} +/** @return {this} */ +Cpp.prototype.m2 = function () { +>Cpp.prototype : Symbol(Cpp.m2, Decl(thisTypeOfConstructorFunctions.js, 27, 1)) +>Cpp : Symbol(Cpp, Decl(thisTypeOfConstructorFunctions.js, 18, 1)) +>prototype : Symbol(Function.prototype, Decl(lib.es5.d.ts, --, --)) +>m2 : Symbol(Cpp.m2, Decl(thisTypeOfConstructorFunctions.js, 27, 1)) + + this.z = this.y; return this +>this.z : Symbol(Cpp.z, Decl(thisTypeOfConstructorFunctions.js, 29, 32)) +>this : Symbol(Cpp, Decl(thisTypeOfConstructorFunctions.js, 18, 1)) +>z : Symbol(Cpp.z, Decl(thisTypeOfConstructorFunctions.js, 29, 32)) +>this.y : Symbol(Cpp.y, Decl(thisTypeOfConstructorFunctions.js, 25, 17)) +>this : Symbol(Cpp, Decl(thisTypeOfConstructorFunctions.js, 18, 1)) +>y : Symbol(Cpp.y, Decl(thisTypeOfConstructorFunctions.js, 25, 17)) +>this : Symbol(Cpp, Decl(thisTypeOfConstructorFunctions.js, 18, 1)) +} + +var cp = new Cp(1) +>cp : Symbol(cp, Decl(thisTypeOfConstructorFunctions.js, 33, 3)) +>Cp : Symbol(Cp, Decl(thisTypeOfConstructorFunctions.js, 0, 0), Decl(thisTypeOfConstructorFunctions.js, 11, 1)) + +var cpp = new Cpp(2) +>cpp : Symbol(cpp, Decl(thisTypeOfConstructorFunctions.js, 34, 3)) +>Cpp : Symbol(Cpp, Decl(thisTypeOfConstructorFunctions.js, 18, 1)) + +cp.dit +>cp.dit : Symbol(Cp.dit, Decl(thisTypeOfConstructorFunctions.js, 5, 16)) +>cp : Symbol(cp, Decl(thisTypeOfConstructorFunctions.js, 33, 3)) +>dit : Symbol(Cp.dit, Decl(thisTypeOfConstructorFunctions.js, 5, 16)) + +/** @type {Cpp} */ +var cppn = cpp.m2() +>cppn : Symbol(cppn, Decl(thisTypeOfConstructorFunctions.js, 38, 3)) +>cpp.m2 : Symbol(Cpp.m2, Decl(thisTypeOfConstructorFunctions.js, 27, 1)) +>cpp : Symbol(cpp, Decl(thisTypeOfConstructorFunctions.js, 34, 3)) +>m2 : Symbol(Cpp.m2, Decl(thisTypeOfConstructorFunctions.js, 27, 1)) + +/** @type {Cp} */ +var cpn = cp.m3() +>cpn : Symbol(cpn, Decl(thisTypeOfConstructorFunctions.js, 41, 3), Decl(thisTypeOfConstructorFunctions.js, 43, 3)) +>cp.m3 : Symbol(Cp.m3, Decl(thisTypeOfConstructorFunctions.js, 8, 14)) +>cp : Symbol(cp, Decl(thisTypeOfConstructorFunctions.js, 33, 3)) +>m3 : Symbol(Cp.m3, Decl(thisTypeOfConstructorFunctions.js, 8, 14)) + +/** @type {Cp} */ +var cpn = cp.m4() +>cpn : Symbol(cpn, Decl(thisTypeOfConstructorFunctions.js, 41, 3), Decl(thisTypeOfConstructorFunctions.js, 43, 3)) +>cp.m4 : Symbol(m4, Decl(thisTypeOfConstructorFunctions.js, 13, 16)) +>cp : Symbol(cp, Decl(thisTypeOfConstructorFunctions.js, 33, 3)) +>m4 : Symbol(m4, Decl(thisTypeOfConstructorFunctions.js, 13, 16)) + + diff --git a/tests/baselines/reference/thisTypeOfConstructorFunctions.types b/tests/baselines/reference/thisTypeOfConstructorFunctions.types new file mode 100644 index 00000000000..126c0c9321a --- /dev/null +++ b/tests/baselines/reference/thisTypeOfConstructorFunctions.types @@ -0,0 +1,137 @@ +=== tests/cases/conformance/salsa/thisTypeOfConstructorFunctions.js === +/** + * @class + * @template T + * @param {T} t + */ +function Cp(t) { +>Cp : typeof Cp +>t : T + + /** @type {this} */ + this.dit = this +>this.dit = this : this +>this.dit : this +>this : this +>dit : this +>this : this + + this.y = t +>this.y = t : T +>this.y : T +>this : this +>y : T +>t : T + + /** @return {this} */ + this.m3 = () => this +>this.m3 = () => this : () => this +>this.m3 : () => this +>this : this +>m3 : () => this +>() => this : () => this +>this : this +} + +Cp.prototype = { +>Cp.prototype = { /** @return {this} */ m4() { this.z = this.y; return this }} : { m4(): this; } +>Cp.prototype : { m4(): this; } +>Cp : typeof Cp +>prototype : { m4(): this; } +>{ /** @return {this} */ m4() { this.z = this.y; return this }} : { m4(): this; } + + /** @return {this} */ + m4() { +>m4 : () => this + + this.z = this.y; return this +>this.z = this.y : T +>this.z : T +>this : this +>z : T +>this.y : T +>this : this +>y : T +>this : this + } +} + +/** + * @class + * @template T + * @param {T} t + */ +function Cpp(t) { +>Cpp : typeof Cpp +>t : T + + this.y = t +>this.y = t : T +>this.y : T +>this : this +>y : T +>t : T +} +/** @return {this} */ +Cpp.prototype.m2 = function () { +>Cpp.prototype.m2 = function () { this.z = this.y; return this} : () => this +>Cpp.prototype.m2 : any +>Cpp.prototype : any +>Cpp : typeof Cpp +>prototype : any +>m2 : any +>function () { this.z = this.y; return this} : () => this + + this.z = this.y; return this +>this.z = this.y : T +>this.z : T +>this : this +>z : T +>this.y : T +>this : this +>y : T +>this : this +} + +var cp = new Cp(1) +>cp : Cp +>new Cp(1) : Cp +>Cp : typeof Cp +>1 : 1 + +var cpp = new Cpp(2) +>cpp : Cpp +>new Cpp(2) : Cpp +>Cpp : typeof Cpp +>2 : 2 + +cp.dit +>cp.dit : Cp +>cp : Cp +>dit : Cp + +/** @type {Cpp} */ +var cppn = cpp.m2() +>cppn : Cpp +>cpp.m2() : Cpp +>cpp.m2 : () => Cpp +>cpp : Cpp +>m2 : () => Cpp + +/** @type {Cp} */ +var cpn = cp.m3() +>cpn : Cp +>cp.m3() : Cp +>cp.m3 : () => Cp +>cp : Cp +>m3 : () => Cp + +/** @type {Cp} */ +var cpn = cp.m4() +>cpn : Cp +>cp.m4() : Cp +>cp.m4 : () => Cp +>cp : Cp +>m4 : () => Cp + + diff --git a/tests/baselines/reference/typeFromJSConstructor.types b/tests/baselines/reference/typeFromJSConstructor.types index d51377c538e..38d736e5a68 100644 --- a/tests/baselines/reference/typeFromJSConstructor.types +++ b/tests/baselines/reference/typeFromJSConstructor.types @@ -60,35 +60,35 @@ Installer.prototype.first = function () { this.arg = 'hi' // error >this.arg = 'hi' : "hi" >this.arg : number ->this : Installer +>this : this >arg : number >'hi' : "hi" this.unknown = 'hi' // ok >this.unknown = 'hi' : "hi" >this.unknown : string | boolean | null ->this : Installer +>this : this >unknown : string | boolean | null >'hi' : "hi" this.newProperty = 1 // ok: number | boolean >this.newProperty = 1 : 1 >this.newProperty : number | boolean | undefined ->this : Installer +>this : this >newProperty : number | boolean | undefined >1 : 1 this.twice = undefined // ok >this.twice = undefined : undefined >this.twice : string | undefined ->this : Installer +>this : this >twice : string | undefined >undefined : undefined this.twice = 'hi' // ok >this.twice = 'hi' : "hi" >this.twice : string | undefined ->this : Installer +>this : this >twice : string | undefined >'hi' : "hi" } @@ -104,35 +104,35 @@ Installer.prototype.second = function () { this.arg = false // error >this.arg = false : false >this.arg : number ->this : Installer +>this : this >arg : number >false : false this.unknown = false // ok >this.unknown = false : false >this.unknown : string | boolean | null ->this : Installer +>this : this >unknown : string | boolean | null >false : false this.newProperty = false // ok >this.newProperty = false : false >this.newProperty : number | boolean | undefined ->this : Installer +>this : this >newProperty : number | boolean | undefined >false : false this.twice = null // error >this.twice = null : null >this.twice : string | undefined ->this : Installer +>this : this >twice : string | undefined >null : null this.twice = false // error >this.twice = false : false >this.twice : string | undefined ->this : Installer +>this : this >twice : string | undefined >false : false @@ -140,7 +140,7 @@ Installer.prototype.second = function () { >this.twices.push(1) : number >this.twices.push : (...items: any[]) => number >this.twices : any[] | null ->this : Installer +>this : this >twices : any[] | null >push : (...items: any[]) => number >1 : 1 @@ -148,7 +148,7 @@ Installer.prototype.second = function () { if (this.twices != null) { >this.twices != null : boolean >this.twices : any[] | null ->this : Installer +>this : this >twices : any[] | null >null : null @@ -156,7 +156,7 @@ Installer.prototype.second = function () { >this.twices.push('hi') : number >this.twices.push : (...items: any[]) => number >this.twices : any[] ->this : Installer +>this : this >twices : any[] >push : (...items: any[]) => number >'hi' : "hi" diff --git a/tests/baselines/reference/typeFromPropertyAssignment11.types b/tests/baselines/reference/typeFromPropertyAssignment11.types index 001003ac76e..f147d0bae4c 100644 --- a/tests/baselines/reference/typeFromPropertyAssignment11.types +++ b/tests/baselines/reference/typeFromPropertyAssignment11.types @@ -36,28 +36,28 @@ Inner.prototype.k; >k : any var inner = new Inner() ->inner : Inner & { m(): void; i: number; } ->new Inner() : Inner & { m(): void; i: number; } +>inner : Inner +>new Inner() : Inner >Inner : typeof Inner inner.m() >inner.m() : void >inner.m : () => void ->inner : Inner & { m(): void; i: number; } +>inner : Inner >m : () => void inner.i >inner.i : number ->inner : Inner & { m(): void; i: number; } +>inner : Inner >i : number inner.j >inner.j : number ->inner : Inner & { m(): void; i: number; } +>inner : Inner >j : number inner.k >inner.k : string ->inner : Inner & { m(): void; i: number; } +>inner : Inner >k : string diff --git a/tests/baselines/reference/typeFromPropertyAssignment12.types b/tests/baselines/reference/typeFromPropertyAssignment12.types index c2bee51375b..21b8dd7e32c 100644 --- a/tests/baselines/reference/typeFromPropertyAssignment12.types +++ b/tests/baselines/reference/typeFromPropertyAssignment12.types @@ -1,7 +1,7 @@ === tests/cases/conformance/salsa/module.js === var Outer = function(element, config) {}; ->Outer : { (element: any, config: any): void; Pos(line: any, ch: any): Pos; } ->function(element, config) {} : { (element: any, config: any): void; Pos(line: any, ch: any): Pos; } +>Outer : { (element: any, config: any): void; Pos(line: any, ch: any): void; } +>function(element, config) {} : { (element: any, config: any): void; Pos(line: any, ch: any): void; } >element : any >config : any @@ -10,7 +10,7 @@ var Outer = function(element, config) {}; Outer.Pos = function (line, ch) {}; >Outer.Pos = function (line, ch) {} : typeof Pos >Outer.Pos : typeof Pos ->Outer : { (element: any, config: any): void; Pos(line: any, ch: any): Pos; } +>Outer : { (element: any, config: any): void; Pos(line: any, ch: any): void; } >Pos : typeof Pos >function (line, ch) {} : typeof Pos >line : any @@ -21,7 +21,7 @@ Outer.Pos.prototype.line; >Outer.Pos.prototype.line : any >Outer.Pos.prototype : any >Outer.Pos : typeof Pos ->Outer : { (element: any, config: any): void; Pos(line: any, ch: any): Pos; } +>Outer : { (element: any, config: any): void; Pos(line: any, ch: any): void; } >Pos : typeof Pos >prototype : any >line : any @@ -30,7 +30,7 @@ var pos = new Outer.Pos(1, 'x'); >pos : Pos >new Outer.Pos(1, 'x') : Pos >Outer.Pos : typeof Pos ->Outer : { (element: any, config: any): void; Pos(line: any, ch: any): Pos; } +>Outer : { (element: any, config: any): void; Pos(line: any, ch: any): void; } >Pos : typeof Pos >1 : 1 >'x' : "x" diff --git a/tests/baselines/reference/typeFromPropertyAssignment13.types b/tests/baselines/reference/typeFromPropertyAssignment13.types index 051b066ffd8..8dbb248af08 100644 --- a/tests/baselines/reference/typeFromPropertyAssignment13.types +++ b/tests/baselines/reference/typeFromPropertyAssignment13.types @@ -49,8 +49,8 @@ Outer.Inner.prototype.k; >k : any var inner = new Outer.Inner() ->inner : Inner & { m(): void; i: number; } ->new Outer.Inner() : Inner & { m(): void; i: number; } +>inner : Inner +>new Outer.Inner() : Inner >Outer.Inner : typeof Inner >Outer : typeof Outer >Inner : typeof Inner @@ -58,21 +58,21 @@ var inner = new Outer.Inner() inner.m() >inner.m() : void >inner.m : () => void ->inner : Inner & { m(): void; i: number; } +>inner : Inner >m : () => void inner.i >inner.i : number ->inner : Inner & { m(): void; i: number; } +>inner : Inner >i : number inner.j >inner.j : number ->inner : Inner & { m(): void; i: number; } +>inner : Inner >j : number inner.k >inner.k : string ->inner : Inner & { m(): void; i: number; } +>inner : Inner >k : string diff --git a/tests/baselines/reference/typeFromPropertyAssignment14.types b/tests/baselines/reference/typeFromPropertyAssignment14.types index bb8169db359..5507fd7967b 100644 --- a/tests/baselines/reference/typeFromPropertyAssignment14.types +++ b/tests/baselines/reference/typeFromPropertyAssignment14.types @@ -31,35 +31,35 @@ Outer.Inner.prototype = { === tests/cases/conformance/salsa/use.js === /** @type {Outer.Inner} */ var inner ->inner : { x: number; m(): void; } +>inner : Inner inner.x >inner.x : number ->inner : { x: number; m(): void; } +>inner : Inner >x : number inner.m() >inner.m() : void >inner.m : () => void ->inner : { x: number; m(): void; } +>inner : Inner >m : () => void var inno = new Outer.Inner() ->inno : { x: number; m(): void; } ->new Outer.Inner() : { x: number; m(): void; } +>inno : Inner +>new Outer.Inner() : Inner >Outer.Inner : typeof Inner >Outer : typeof Outer >Inner : typeof Inner inno.x >inno.x : number ->inno : { x: number; m(): void; } +>inno : Inner >x : number inno.m() >inno.m() : void >inno.m : () => void ->inno : { x: number; m(): void; } +>inno : Inner >m : () => void diff --git a/tests/baselines/reference/typeFromPropertyAssignment16.types b/tests/baselines/reference/typeFromPropertyAssignment16.types index 1d94d096ea0..506e12895c2 100644 --- a/tests/baselines/reference/typeFromPropertyAssignment16.types +++ b/tests/baselines/reference/typeFromPropertyAssignment16.types @@ -29,34 +29,34 @@ Outer.Inner.prototype = { /** @type {Outer.Inner} */ var inner ->inner : { x: number; m(): void; } +>inner : Inner inner.x >inner.x : number ->inner : { x: number; m(): void; } +>inner : Inner >x : number inner.m() >inner.m() : void >inner.m : () => void ->inner : { x: number; m(): void; } +>inner : Inner >m : () => void var inno = new Outer.Inner() ->inno : { x: number; m(): void; } ->new Outer.Inner() : { x: number; m(): void; } +>inno : Inner +>new Outer.Inner() : Inner >Outer.Inner : typeof Inner >Outer : typeof Outer >Inner : typeof Inner inno.x >inno.x : number ->inno : { x: number; m(): void; } +>inno : Inner >x : number inno.m() >inno.m() : void >inno.m : () => void ->inno : { x: number; m(): void; } +>inno : Inner >m : () => void diff --git a/tests/baselines/reference/typeFromPropertyAssignment20.types b/tests/baselines/reference/typeFromPropertyAssignment20.types index b31536002bd..32e1b541d7b 100644 --- a/tests/baselines/reference/typeFromPropertyAssignment20.types +++ b/tests/baselines/reference/typeFromPropertyAssignment20.types @@ -39,7 +39,7 @@ this._trampolineEnabled = false; >this._trampolineEnabled = false : false >this._trampolineEnabled : boolean ->this : Async +>this : this >_trampolineEnabled : boolean >false : false } diff --git a/tests/baselines/reference/typeFromPropertyAssignment22.types b/tests/baselines/reference/typeFromPropertyAssignment22.types index 204f68df13f..1c4d6822578 100644 --- a/tests/baselines/reference/typeFromPropertyAssignment22.types +++ b/tests/baselines/reference/typeFromPropertyAssignment22.types @@ -27,14 +27,14 @@ Installer.prototype.loadArgMetadata = function (next) { this.args = 'hi' >this.args = 'hi' : "hi" >this.args : number ->this : Installer +>this : this >args : number >'hi' : "hi" this.newProperty = 1 >this.newProperty = 1 : 1 >this.newProperty : number | undefined ->this : Installer +>this : this >newProperty : number | undefined >1 : 1 } diff --git a/tests/baselines/reference/typeFromPropertyAssignment27.types b/tests/baselines/reference/typeFromPropertyAssignment27.types index b7c3557c86e..956979e805a 100644 --- a/tests/baselines/reference/typeFromPropertyAssignment27.types +++ b/tests/baselines/reference/typeFromPropertyAssignment27.types @@ -18,17 +18,17 @@ C.prototype = { q: 2 }; >2 : 2 const c = new C() ->c : C & { q: number; } ->new C() : C & { q: number; } +>c : C +>new C() : C >C : typeof C c.p >c.p : number ->c : C & { q: number; } +>c : C >p : number c.q >c.q : number ->c : C & { q: number; } +>c : C >q : number diff --git a/tests/baselines/reference/typeFromPrototypeAssignment.symbols b/tests/baselines/reference/typeFromPrototypeAssignment.symbols index d51382a639f..74dbf3dc2c0 100644 --- a/tests/baselines/reference/typeFromPrototypeAssignment.symbols +++ b/tests/baselines/reference/typeFromPrototypeAssignment.symbols @@ -7,22 +7,27 @@ var Multimap = function() { this._map = {}; >this._map : Symbol(Multimap._map, Decl(a.js, 3, 27)) +>this : Symbol(Multimap, Decl(a.js, 3, 14)) >_map : Symbol(Multimap._map, Decl(a.js, 3, 27)) this._map >this._map : Symbol(Multimap._map, Decl(a.js, 3, 27)) +>this : Symbol(Multimap, Decl(a.js, 3, 14)) >_map : Symbol(Multimap._map, Decl(a.js, 3, 27)) this.set >this.set : Symbol(set, Decl(a.js, 11, 22)) +>this : Symbol(Multimap, Decl(a.js, 3, 14)) >set : Symbol(set, Decl(a.js, 11, 22)) this.get >this.get : Symbol(get, Decl(a.js, 17, 6)) +>this : Symbol(Multimap, Decl(a.js, 3, 14)) >get : Symbol(get, Decl(a.js, 17, 6)) this.addon >this.addon : Symbol(Multimap.addon, Decl(a.js, 24, 1)) +>this : Symbol(Multimap, Decl(a.js, 3, 14)) >addon : Symbol(Multimap.addon, Decl(a.js, 24, 1)) }; @@ -37,18 +42,22 @@ Multimap.prototype = { this._map >this._map : Symbol(Multimap._map, Decl(a.js, 3, 27)) +>this : Symbol(Multimap, Decl(a.js, 3, 14)) >_map : Symbol(Multimap._map, Decl(a.js, 3, 27)) this.set >this.set : Symbol(set, Decl(a.js, 11, 22)) +>this : Symbol(Multimap, Decl(a.js, 3, 14)) >set : Symbol(set, Decl(a.js, 11, 22)) this.get >this.get : Symbol(get, Decl(a.js, 17, 6)) +>this : Symbol(Multimap, Decl(a.js, 3, 14)) >get : Symbol(get, Decl(a.js, 17, 6)) this.addon >this.addon : Symbol(Multimap.addon, Decl(a.js, 24, 1)) +>this : Symbol(Multimap, Decl(a.js, 3, 14)) >addon : Symbol(Multimap.addon, Decl(a.js, 24, 1)) }, @@ -57,18 +66,22 @@ Multimap.prototype = { this._map >this._map : Symbol(Multimap._map, Decl(a.js, 3, 27)) +>this : Symbol(Multimap, Decl(a.js, 3, 14)) >_map : Symbol(Multimap._map, Decl(a.js, 3, 27)) this.set >this.set : Symbol(set, Decl(a.js, 11, 22)) +>this : Symbol(Multimap, Decl(a.js, 3, 14)) >set : Symbol(set, Decl(a.js, 11, 22)) this.get >this.get : Symbol(get, Decl(a.js, 17, 6)) +>this : Symbol(Multimap, Decl(a.js, 3, 14)) >get : Symbol(get, Decl(a.js, 17, 6)) this.addon >this.addon : Symbol(Multimap.addon, Decl(a.js, 24, 1)) +>this : Symbol(Multimap, Decl(a.js, 3, 14)) >addon : Symbol(Multimap.addon, Decl(a.js, 24, 1)) } } @@ -81,18 +94,22 @@ Multimap.prototype.addon = function () { this._map >this._map : Symbol(Multimap._map, Decl(a.js, 3, 27)) +>this : Symbol(Multimap, Decl(a.js, 3, 14)) >_map : Symbol(Multimap._map, Decl(a.js, 3, 27)) this.set >this.set : Symbol(set, Decl(a.js, 11, 22)) +>this : Symbol(Multimap, Decl(a.js, 3, 14)) >set : Symbol(set, Decl(a.js, 11, 22)) this.get >this.get : Symbol(get, Decl(a.js, 17, 6)) +>this : Symbol(Multimap, Decl(a.js, 3, 14)) >get : Symbol(get, Decl(a.js, 17, 6)) this.addon >this.addon : Symbol(Multimap.addon, Decl(a.js, 24, 1)) +>this : Symbol(Multimap, Decl(a.js, 3, 14)) >addon : Symbol(Multimap.addon, Decl(a.js, 24, 1)) } diff --git a/tests/baselines/reference/typeFromPrototypeAssignment.types b/tests/baselines/reference/typeFromPrototypeAssignment.types index 87e4be5e0b9..1e8aee1e1ba 100644 --- a/tests/baselines/reference/typeFromPrototypeAssignment.types +++ b/tests/baselines/reference/typeFromPrototypeAssignment.types @@ -9,28 +9,28 @@ var Multimap = function() { this._map = {}; >this._map = {} : {} >this._map : {} ->this : Multimap & { set: () => void; get(): void; } +>this : this >_map : {} >{} : {} this._map >this._map : {} ->this : Multimap & { set: () => void; get(): void; } +>this : this >_map : {} this.set >this.set : () => void ->this : Multimap & { set: () => void; get(): void; } +>this : this >set : () => void this.get >this.get : () => void ->this : Multimap & { set: () => void; get(): void; } +>this : this >get : () => void this.addon >this.addon : () => void ->this : Multimap & { set: () => void; get(): void; } +>this : this >addon : () => void }; @@ -48,22 +48,22 @@ Multimap.prototype = { this._map >this._map : {} ->this : Multimap & { set: () => void; get(): void; } +>this : this >_map : {} this.set >this.set : () => void ->this : Multimap & { set: () => void; get(): void; } +>this : this >set : () => void this.get >this.get : () => void ->this : Multimap & { set: () => void; get(): void; } +>this : this >get : () => void this.addon >this.addon : () => void ->this : Multimap & { set: () => void; get(): void; } +>this : this >addon : () => void }, @@ -72,22 +72,22 @@ Multimap.prototype = { this._map >this._map : {} ->this : Multimap & { set: () => void; get(): void; } +>this : this >_map : {} this.set >this.set : () => void ->this : Multimap & { set: () => void; get(): void; } +>this : this >set : () => void this.get >this.get : () => void ->this : Multimap & { set: () => void; get(): void; } +>this : this >get : () => void this.addon >this.addon : () => void ->this : Multimap & { set: () => void; get(): void; } +>this : this >addon : () => void } } @@ -103,47 +103,47 @@ Multimap.prototype.addon = function () { this._map >this._map : {} ->this : Multimap & { set: () => void; get(): void; } +>this : this >_map : {} this.set >this.set : () => void ->this : Multimap & { set: () => void; get(): void; } +>this : this >set : () => void this.get >this.get : () => void ->this : Multimap & { set: () => void; get(): void; } +>this : this >get : () => void this.addon >this.addon : () => void ->this : Multimap & { set: () => void; get(): void; } +>this : this >addon : () => void } var mm = new Multimap(); ->mm : Multimap & { set: () => void; get(): void; } ->new Multimap() : Multimap & { set: () => void; get(): void; } +>mm : Multimap +>new Multimap() : Multimap >Multimap : typeof Multimap mm._map >mm._map : {} ->mm : Multimap & { set: () => void; get(): void; } +>mm : Multimap >_map : {} mm.set >mm.set : () => void ->mm : Multimap & { set: () => void; get(): void; } +>mm : Multimap >set : () => void mm.get >mm.get : () => void ->mm : Multimap & { set: () => void; get(): void; } +>mm : Multimap >get : () => void mm.addon >mm.addon : () => void ->mm : Multimap & { set: () => void; get(): void; } +>mm : Multimap >addon : () => void diff --git a/tests/baselines/reference/typeFromPrototypeAssignment2.symbols b/tests/baselines/reference/typeFromPrototypeAssignment2.symbols index 25ae9e31c69..5d56928f267 100644 --- a/tests/baselines/reference/typeFromPrototypeAssignment2.symbols +++ b/tests/baselines/reference/typeFromPrototypeAssignment2.symbols @@ -10,22 +10,27 @@ this._map = {}; >this._map : Symbol(Multimap._map, Decl(a.js, 4, 31)) +>this : Symbol(Multimap, Decl(a.js, 4, 18)) >_map : Symbol(Multimap._map, Decl(a.js, 4, 31)) this._map >this._map : Symbol(Multimap._map, Decl(a.js, 4, 31)) +>this : Symbol(Multimap, Decl(a.js, 4, 18)) >_map : Symbol(Multimap._map, Decl(a.js, 4, 31)) this.set >this.set : Symbol(set, Decl(a.js, 12, 26)) +>this : Symbol(Multimap, Decl(a.js, 4, 18)) >set : Symbol(set, Decl(a.js, 12, 26)) this.get >this.get : Symbol(get, Decl(a.js, 18, 10)) +>this : Symbol(Multimap, Decl(a.js, 4, 18)) >get : Symbol(get, Decl(a.js, 18, 10)) this.addon >this.addon : Symbol(Multimap.addon, Decl(a.js, 25, 5)) +>this : Symbol(Multimap, Decl(a.js, 4, 18)) >addon : Symbol(Multimap.addon, Decl(a.js, 25, 5)) }; @@ -40,18 +45,22 @@ this._map >this._map : Symbol(Multimap._map, Decl(a.js, 4, 31)) +>this : Symbol(Multimap, Decl(a.js, 4, 18)) >_map : Symbol(Multimap._map, Decl(a.js, 4, 31)) this.set >this.set : Symbol(set, Decl(a.js, 12, 26)) +>this : Symbol(Multimap, Decl(a.js, 4, 18)) >set : Symbol(set, Decl(a.js, 12, 26)) this.get >this.get : Symbol(get, Decl(a.js, 18, 10)) +>this : Symbol(Multimap, Decl(a.js, 4, 18)) >get : Symbol(get, Decl(a.js, 18, 10)) this.addon >this.addon : Symbol(Multimap.addon, Decl(a.js, 25, 5)) +>this : Symbol(Multimap, Decl(a.js, 4, 18)) >addon : Symbol(Multimap.addon, Decl(a.js, 25, 5)) }, @@ -60,18 +69,22 @@ this._map >this._map : Symbol(Multimap._map, Decl(a.js, 4, 31)) +>this : Symbol(Multimap, Decl(a.js, 4, 18)) >_map : Symbol(Multimap._map, Decl(a.js, 4, 31)) this.set >this.set : Symbol(set, Decl(a.js, 12, 26)) +>this : Symbol(Multimap, Decl(a.js, 4, 18)) >set : Symbol(set, Decl(a.js, 12, 26)) this.get >this.get : Symbol(get, Decl(a.js, 18, 10)) +>this : Symbol(Multimap, Decl(a.js, 4, 18)) >get : Symbol(get, Decl(a.js, 18, 10)) this.addon >this.addon : Symbol(Multimap.addon, Decl(a.js, 25, 5)) +>this : Symbol(Multimap, Decl(a.js, 4, 18)) >addon : Symbol(Multimap.addon, Decl(a.js, 25, 5)) } } @@ -84,18 +97,22 @@ this._map >this._map : Symbol(Multimap._map, Decl(a.js, 4, 31)) +>this : Symbol(Multimap, Decl(a.js, 4, 18)) >_map : Symbol(Multimap._map, Decl(a.js, 4, 31)) this.set >this.set : Symbol(set, Decl(a.js, 12, 26)) +>this : Symbol(Multimap, Decl(a.js, 4, 18)) >set : Symbol(set, Decl(a.js, 12, 26)) this.get >this.get : Symbol(get, Decl(a.js, 18, 10)) +>this : Symbol(Multimap, Decl(a.js, 4, 18)) >get : Symbol(get, Decl(a.js, 18, 10)) this.addon >this.addon : Symbol(Multimap.addon, Decl(a.js, 25, 5)) +>this : Symbol(Multimap, Decl(a.js, 4, 18)) >addon : Symbol(Multimap.addon, Decl(a.js, 25, 5)) } diff --git a/tests/baselines/reference/typeFromPrototypeAssignment2.types b/tests/baselines/reference/typeFromPrototypeAssignment2.types index d37f421a356..1a484ba8fc8 100644 --- a/tests/baselines/reference/typeFromPrototypeAssignment2.types +++ b/tests/baselines/reference/typeFromPrototypeAssignment2.types @@ -14,28 +14,28 @@ this._map = {}; >this._map = {} : {} >this._map : {} ->this : Multimap & { set: () => void; get(): void; } +>this : this >_map : {} >{} : {} this._map >this._map : {} ->this : Multimap & { set: () => void; get(): void; } +>this : this >_map : {} this.set >this.set : () => void ->this : Multimap & { set: () => void; get(): void; } +>this : this >set : () => void this.get >this.get : () => void ->this : Multimap & { set: () => void; get(): void; } +>this : this >get : () => void this.addon >this.addon : () => void ->this : Multimap & { set: () => void; get(): void; } +>this : this >addon : () => void }; @@ -53,22 +53,22 @@ this._map >this._map : {} ->this : Multimap & { set: () => void; get(): void; } +>this : this >_map : {} this.set >this.set : () => void ->this : Multimap & { set: () => void; get(): void; } +>this : this >set : () => void this.get >this.get : () => void ->this : Multimap & { set: () => void; get(): void; } +>this : this >get : () => void this.addon >this.addon : () => void ->this : Multimap & { set: () => void; get(): void; } +>this : this >addon : () => void }, @@ -77,22 +77,22 @@ this._map >this._map : {} ->this : Multimap & { set: () => void; get(): void; } +>this : this >_map : {} this.set >this.set : () => void ->this : Multimap & { set: () => void; get(): void; } +>this : this >set : () => void this.get >this.get : () => void ->this : Multimap & { set: () => void; get(): void; } +>this : this >get : () => void this.addon >this.addon : () => void ->this : Multimap & { set: () => void; get(): void; } +>this : this >addon : () => void } } @@ -108,48 +108,48 @@ this._map >this._map : {} ->this : Multimap & { set: () => void; get(): void; } +>this : this >_map : {} this.set >this.set : () => void ->this : Multimap & { set: () => void; get(): void; } +>this : this >set : () => void this.get >this.get : () => void ->this : Multimap & { set: () => void; get(): void; } +>this : this >get : () => void this.addon >this.addon : () => void ->this : Multimap & { set: () => void; get(): void; } +>this : this >addon : () => void } var mm = new Multimap(); ->mm : Multimap & { set: () => void; get(): void; } ->new Multimap() : Multimap & { set: () => void; get(): void; } +>mm : Multimap +>new Multimap() : Multimap >Multimap : typeof Multimap mm._map >mm._map : {} ->mm : Multimap & { set: () => void; get(): void; } +>mm : Multimap >_map : {} mm.set >mm.set : () => void ->mm : Multimap & { set: () => void; get(): void; } +>mm : Multimap >set : () => void mm.get >mm.get : () => void ->mm : Multimap & { set: () => void; get(): void; } +>mm : Multimap >get : () => void mm.addon >mm.addon : () => void ->mm : Multimap & { set: () => void; get(): void; } +>mm : Multimap >addon : () => void }); diff --git a/tests/baselines/reference/typeFromPrototypeAssignment3.symbols b/tests/baselines/reference/typeFromPrototypeAssignment3.symbols index 65b72e9441b..aec60e00543 100644 --- a/tests/baselines/reference/typeFromPrototypeAssignment3.symbols +++ b/tests/baselines/reference/typeFromPrototypeAssignment3.symbols @@ -22,6 +22,7 @@ Multimap3.prototype = { return this._map[key + '']; >this._map : Symbol(Multimap3._map, Decl(bug26885.js, 0, 22)) +>this : Symbol(Multimap3, Decl(bug26885.js, 0, 0), Decl(bug26885.js, 2, 2)) >_map : Symbol(Multimap3._map, Decl(bug26885.js, 0, 22)) >key : Symbol(key, Decl(bug26885.js, 9, 8)) } diff --git a/tests/baselines/reference/typeFromPrototypeAssignment3.types b/tests/baselines/reference/typeFromPrototypeAssignment3.types index 82fef59c42a..73eccd53906 100644 --- a/tests/baselines/reference/typeFromPrototypeAssignment3.types +++ b/tests/baselines/reference/typeFromPrototypeAssignment3.types @@ -29,7 +29,7 @@ Multimap3.prototype = { return this._map[key + '']; >this._map[key + ''] : any >this._map : {} ->this : Multimap3 & { get(key: string): number; } +>this : this >_map : {} >key + '' : string >key : string @@ -39,15 +39,15 @@ Multimap3.prototype = { /** @type {Multimap3} */ const map = new Multimap3(); ->map : Multimap3 & { get(key: string): number; } ->new Multimap3() : Multimap3 & { get(key: string): number; } +>map : Multimap3 +>new Multimap3() : Multimap3 >Multimap3 : typeof Multimap3 const n = map.get('hi') >n : number >map.get('hi') : number >map.get : (key: string) => number ->map : Multimap3 & { get(key: string): number; } +>map : Multimap3 >get : (key: string) => number >'hi' : "hi" diff --git a/tests/baselines/reference/umd-augmentation-2.symbols b/tests/baselines/reference/umd-augmentation-2.symbols index c083dc35bf8..d24f1367f83 100644 --- a/tests/baselines/reference/umd-augmentation-2.symbols +++ b/tests/baselines/reference/umd-augmentation-2.symbols @@ -3,9 +3,9 @@ /// let v = new Math2d.Vector(3, 2); >v : Symbol(v, Decl(a.ts, 2, 3)) ->Math2d.Vector : Symbol(Math2d.Vector, Decl(index.d.ts, 5, 1)) +>Math2d.Vector : Symbol(Vector, Decl(index.d.ts, 5, 1), Decl(math2d-augment.d.ts, 2, 25)) >Math2d : Symbol(Math2d, Decl(index.d.ts, 0, 0)) ->Vector : Symbol(Math2d.Vector, Decl(index.d.ts, 5, 1)) +>Vector : Symbol(Vector, Decl(index.d.ts, 5, 1), Decl(math2d-augment.d.ts, 2, 25)) let magnitude = Math2d.getLength(v); >magnitude : Symbol(magnitude, Decl(a.ts, 3, 3)) diff --git a/tests/baselines/reference/umd-augmentation-2.types b/tests/baselines/reference/umd-augmentation-2.types index 305dc10abf5..45b4f7f855d 100644 --- a/tests/baselines/reference/umd-augmentation-2.types +++ b/tests/baselines/reference/umd-augmentation-2.types @@ -4,9 +4,9 @@ let v = new Math2d.Vector(3, 2); >v : import("tests/cases/conformance/externalModules/node_modules/math2d/index").Vector >new Math2d.Vector(3, 2) : import("tests/cases/conformance/externalModules/node_modules/math2d/index").Vector ->Math2d.Vector : typeof Math2d.Vector +>Math2d.Vector : typeof import("tests/cases/conformance/externalModules/node_modules/math2d/index").Vector >Math2d : typeof Math2d ->Vector : typeof Math2d.Vector +>Vector : typeof import("tests/cases/conformance/externalModules/node_modules/math2d/index").Vector >3 : 3 >2 : 2 diff --git a/tests/cases/conformance/jsdoc/jsdocTemplateConstructorFunction2.ts b/tests/cases/conformance/jsdoc/jsdocTemplateConstructorFunction2.ts index d0418661bb7..623b1c28a4f 100644 --- a/tests/cases/conformance/jsdoc/jsdocTemplateConstructorFunction2.ts +++ b/tests/cases/conformance/jsdoc/jsdocTemplateConstructorFunction2.ts @@ -24,6 +24,8 @@ Zet.prototype.add = function(v, o) { var z = new Zet(1) z.t = 2 z.u = false +/** @type {number} */ +let answer = z.add(3, { nested: 4 }) // lookup in typedef should not crash the compiler, even when the type is unknown /** diff --git a/tests/cases/conformance/salsa/propertiesOfGenericConstructorFunctions.ts b/tests/cases/conformance/salsa/propertiesOfGenericConstructorFunctions.ts new file mode 100644 index 00000000000..71d289e0813 --- /dev/null +++ b/tests/cases/conformance/salsa/propertiesOfGenericConstructorFunctions.ts @@ -0,0 +1,56 @@ +// @Filename: propertiesOfGenericConstructorFunctions.js +// @allowJs: true +// @checkJs: true +// @noEmit: true + +/** + * @template {string} K + * @template V + * @param {string} ik + * @param {V} iv + */ +function Multimap(ik, iv) { + /** @type {{ [s: string]: V }} */ + this._map = {}; + // without type annotation + this._map2 = { [ik]: iv }; +}; + +/** @type {Multimap<"a" | "b", number>} with type annotation */ +const map = new Multimap("a", 1); +// without type annotation +const map2 = new Multimap("m", 2); + +/** @type {number} */ +var n = map._map['hi'] +/** @type {number} */ +var n = map._map2['hi'] +/** @type {number} */ +var n = map2._map['hi'] +/** @type {number} */ +var n = map._map2['hi'] + +/** + * @class + * @template T + * @param {T} t + */ +function Cp(t) { + this.x = 1 + this.y = t +} +Cp.prototype = { + m1() { return this.x }, + m2() { this.z = this.x + 1; return this.y } +} +var cp = new Cp(1) + +/** @type {number} */ +var n = cp.x +/** @type {number} */ +var n = cp.y +/** @type {number} */ +var n = cp.m1() +/** @type {number} */ +var n = cp.m2() + diff --git a/tests/cases/conformance/salsa/prototypePropertyAssignmentMergeAcrossFiles.ts b/tests/cases/conformance/salsa/prototypePropertyAssignmentMergeAcrossFiles.ts new file mode 100644 index 00000000000..e440afd7a24 --- /dev/null +++ b/tests/cases/conformance/salsa/prototypePropertyAssignmentMergeAcrossFiles.ts @@ -0,0 +1,10 @@ +// @Filename: prototypePropertyAssignmentMergeAcrossFiles.js +// @allowJs: true +// @checkJs: true +// @noEmit: true +function C() { + this.a = 1 +} + +// @Filename: other.js +C.prototype.foo = function() { return this.a } diff --git a/tests/cases/conformance/salsa/thisTypeOfConstructorFunctions.ts b/tests/cases/conformance/salsa/thisTypeOfConstructorFunctions.ts new file mode 100644 index 00000000000..413b9949602 --- /dev/null +++ b/tests/cases/conformance/salsa/thisTypeOfConstructorFunctions.ts @@ -0,0 +1,50 @@ +// @Filename: thisTypeOfConstructorFunctions.js +// @allowJs: true +// @checkJs: true +// @noEmit: true + +/** + * @class + * @template T + * @param {T} t + */ +function Cp(t) { + /** @type {this} */ + this.dit = this + this.y = t + /** @return {this} */ + this.m3 = () => this +} + +Cp.prototype = { + /** @return {this} */ + m4() { + this.z = this.y; return this + } +} + +/** + * @class + * @template T + * @param {T} t + */ +function Cpp(t) { + this.y = t +} +/** @return {this} */ +Cpp.prototype.m2 = function () { + this.z = this.y; return this +} + +var cp = new Cp(1) +var cpp = new Cpp(2) +cp.dit + +/** @type {Cpp} */ +var cppn = cpp.m2() + +/** @type {Cp} */ +var cpn = cp.m3() +/** @type {Cp} */ +var cpn = cp.m4() + diff --git a/tests/cases/fourslash/jsDocFunctionSignatures8.ts b/tests/cases/fourslash/jsDocFunctionSignatures8.ts index f7f2f4dca5e..e34fb30dbfb 100644 --- a/tests/cases/fourslash/jsDocFunctionSignatures8.ts +++ b/tests/cases/fourslash/jsDocFunctionSignatures8.ts @@ -14,4 +14,4 @@ ////} ////var p = new Pers/**/on(); goTo.marker(); -verify.quickInfoIs("function Person(name: string, age: number): Person", "Represents a person\na b multiline test"); +verify.quickInfoIs("constructor Person(name: string, age: number): Person", "Represents a person\na b multiline test"); From 1bf218291f3c839efd01920082bad4d663cd1ad5 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Mon, 19 Aug 2019 18:13:39 -0700 Subject: [PATCH 10/10] Fix default behavior for transpileModule when fileName not provided (#32982) --- src/services/transpile.ts | 2 +- src/testRunner/unittests/services/transpile.ts | 15 ++++++++++++--- .../transpile/Infer correct file extension.js | 2 ++ .../Infer correct file extension.oldTranspile.js | 2 ++ 4 files changed, 17 insertions(+), 4 deletions(-) create mode 100644 tests/baselines/reference/transpile/Infer correct file extension.js create mode 100644 tests/baselines/reference/transpile/Infer correct file extension.oldTranspile.js diff --git a/src/services/transpile.ts b/src/services/transpile.ts index bdc27ac5e22..51d1582c564 100644 --- a/src/services/transpile.ts +++ b/src/services/transpile.ts @@ -66,7 +66,7 @@ namespace ts { options.noResolve = true; // if jsx is specified then treat file as .tsx - const inputFileName = transpileOptions.fileName || (options.jsx ? "module.tsx" : "module.ts"); + const inputFileName = transpileOptions.fileName || (transpileOptions.compilerOptions && transpileOptions.compilerOptions.jsx ? "module.tsx" : "module.ts"); const sourceFile = createSourceFile(inputFileName, input, options.target!); // TODO: GH#18217 if (transpileOptions.moduleName) { sourceFile.moduleName = transpileOptions.moduleName; diff --git a/src/testRunner/unittests/services/transpile.ts b/src/testRunner/unittests/services/transpile.ts index 6e8f3bcac9c..a86f4bdfc9e 100644 --- a/src/testRunner/unittests/services/transpile.ts +++ b/src/testRunner/unittests/services/transpile.ts @@ -3,6 +3,7 @@ namespace ts { interface TranspileTestSettings { options?: TranspileOptions; + noSetFileName?: boolean; } function transpilesCorrectly(name: string, input: string, testSettings: TranspileTestSettings) { @@ -30,15 +31,19 @@ namespace ts { transpileOptions.compilerOptions.sourceMap = true; - if (!transpileOptions.fileName) { - transpileOptions.fileName = transpileOptions.compilerOptions.jsx ? "file.tsx" : "file.ts"; + let unitName = transpileOptions.fileName; + if (!unitName) { + unitName = transpileOptions.compilerOptions.jsx ? "file.tsx" : "file.ts"; + if (!testSettings.noSetFileName) { + transpileOptions.fileName = unitName; + } } transpileOptions.reportDiagnostics = true; justName = "transpile/" + name.replace(/[^a-z0-9\-. ]/ig, "") + (transpileOptions.compilerOptions.jsx ? Extension.Tsx : Extension.Ts); toBeCompiled = [{ - unitName: transpileOptions.fileName, + unitName, content: input }]; @@ -456,5 +461,9 @@ var x = 0;`, { transpilesCorrectly("Supports 'as const' arrays", `([] as const).forEach(k => console.log(k));`, { options: { compilerOptions: { module: ModuleKind.CommonJS } } }); + + transpilesCorrectly("Infer correct file extension", `const fn = (a: T) => a`, { + noSetFileName: true + }); }); } diff --git a/tests/baselines/reference/transpile/Infer correct file extension.js b/tests/baselines/reference/transpile/Infer correct file extension.js new file mode 100644 index 00000000000..76701b98d64 --- /dev/null +++ b/tests/baselines/reference/transpile/Infer correct file extension.js @@ -0,0 +1,2 @@ +var fn = function (a) { return a; }; +//# sourceMappingURL=module.js.map \ No newline at end of file diff --git a/tests/baselines/reference/transpile/Infer correct file extension.oldTranspile.js b/tests/baselines/reference/transpile/Infer correct file extension.oldTranspile.js new file mode 100644 index 00000000000..76701b98d64 --- /dev/null +++ b/tests/baselines/reference/transpile/Infer correct file extension.oldTranspile.js @@ -0,0 +1,2 @@ +var fn = function (a) { return a; }; +//# sourceMappingURL=module.js.map \ No newline at end of file