diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f8fd620213241..d1a104b906538 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -9166,12 +9166,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 { @@ -9363,10 +9363,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 0000000000000..32a9543fbf768 --- /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 0000000000000..df50c0635e268 --- /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 : { <T>(a: T[]): readonly T[]; <T extends Function>(f: T): T; <T>(o: T): Readonly<T>; } +>Object : ObjectConstructor +>freeze : { <T>(a: T[]): readonly T[]; <T extends Function>(f: T): T; <T>(o: T): Readonly<T>; } +>{ 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 0000000000000..a8414d68ad736 --- /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/TypeScript-Node-Starter/TypeScript-Node-Starter b/tests/cases/user/TypeScript-Node-Starter/TypeScript-Node-Starter index 40bdb4eadabc9..1bf5836cae524 160000 --- a/tests/cases/user/TypeScript-Node-Starter/TypeScript-Node-Starter +++ b/tests/cases/user/TypeScript-Node-Starter/TypeScript-Node-Starter @@ -1 +1 @@ -Subproject commit 40bdb4eadabc9fbed7d83e3f26817a931c0763b6 +Subproject commit 1bf5836cae5246b89bbf7063c3e84e110222fcdf diff --git a/tests/cases/user/TypeScript-React-Native-Starter/TypeScript-React-Native-Starter b/tests/cases/user/TypeScript-React-Native-Starter/TypeScript-React-Native-Starter index ef797268ddfe9..30acce5e136e8 160000 --- a/tests/cases/user/TypeScript-React-Native-Starter/TypeScript-React-Native-Starter +++ b/tests/cases/user/TypeScript-React-Native-Starter/TypeScript-React-Native-Starter @@ -1 +1 @@ -Subproject commit ef797268ddfe9b2e5d2273b953eebdbffb4f734c +Subproject commit 30acce5e136e86bcf4eff1df151742f78142aa1a diff --git a/tests/cases/user/TypeScript-React-Starter/TypeScript-React-Starter b/tests/cases/user/TypeScript-React-Starter/TypeScript-React-Starter index 1404377597038..bfc20b2f17c02 160000 --- a/tests/cases/user/TypeScript-React-Starter/TypeScript-React-Starter +++ b/tests/cases/user/TypeScript-React-Starter/TypeScript-React-Starter @@ -1 +1 @@ -Subproject commit 1404377597038d22c9df43b49ced70bae635edba +Subproject commit bfc20b2f17c0206105e2cdd42cd35d79dd03a884 diff --git a/tests/cases/user/TypeScript-Vue-Starter/TypeScript-Vue-Starter b/tests/cases/user/TypeScript-Vue-Starter/TypeScript-Vue-Starter index c243b11a6f827..56024cfe41449 160000 --- a/tests/cases/user/TypeScript-Vue-Starter/TypeScript-Vue-Starter +++ b/tests/cases/user/TypeScript-Vue-Starter/TypeScript-Vue-Starter @@ -1 +1 @@ -Subproject commit c243b11a6f827e780a5163999bc472c95ff5a0e0 +Subproject commit 56024cfe414491a9097e9dd33661a5ad5d51d975 diff --git a/tests/cases/user/axios-src/axios-src b/tests/cases/user/axios-src/axios-src index 283d7b306ce23..2ee3b482456cd 160000 --- a/tests/cases/user/axios-src/axios-src +++ b/tests/cases/user/axios-src/axios-src @@ -1 +1 @@ -Subproject commit 283d7b306ce231f092d28e01713905e5c1600d14 +Subproject commit 2ee3b482456cd2a09ccbd3a4b0c20f3d0c5a5644 diff --git a/tests/cases/user/create-react-app/create-react-app b/tests/cases/user/create-react-app/create-react-app index 1a61db58d434d..437b83f0337a5 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 1a61db58d434d33603f20e73ca643ec83c561b73 +Subproject commit 437b83f0337a5d57ce7dd976d2c3b44cb2037e45 diff --git a/tests/cases/user/prettier/prettier b/tests/cases/user/prettier/prettier index 1e471a007968b..2314640485001 160000 --- a/tests/cases/user/prettier/prettier +++ b/tests/cases/user/prettier/prettier @@ -1 +1 @@ -Subproject commit 1e471a007968b7490563b91ed6909ae6046f3fe8 +Subproject commit 23146404850011972f695fb6bc2b8113c3cffbfc diff --git a/tests/cases/user/puppeteer/puppeteer b/tests/cases/user/puppeteer/puppeteer index 2c6df6ddd1aeb..b6b29502eb6a7 160000 --- a/tests/cases/user/puppeteer/puppeteer +++ b/tests/cases/user/puppeteer/puppeteer @@ -1 +1 @@ -Subproject commit 2c6df6ddd1aeb39b6858a1b7c980fe20079230da +Subproject commit b6b29502eb6a75fe3869806f0e7b27195fe51b0d diff --git a/tests/cases/user/webpack/webpack b/tests/cases/user/webpack/webpack index dc2668873162f..743ae6da9a6fc 160000 --- a/tests/cases/user/webpack/webpack +++ b/tests/cases/user/webpack/webpack @@ -1 +1 @@ -Subproject commit dc2668873162ff3369eb8787c1b79f909650e040 +Subproject commit 743ae6da9a6fc3b459a7ab3bb250fb07d14f9c5d