From 5128e06a9dba99150b3f116ff46477d0f8a4d1bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Thu, 20 Jul 2023 22:20:47 +0200 Subject: [PATCH] Fixed expando functions with symbol-only properties (#54726) --- src/compiler/checker.ts | 21 ++++---- .../expandoFunctionSymbolProperty.js | 37 +++++++++++++ .../expandoFunctionSymbolProperty.symbols | 33 ++++++++++++ .../expandoFunctionSymbolProperty.types | 34 ++++++++++++ .../expandoFunctionSymbolPropertyJs.js | 54 +++++++++++++++++++ .../expandoFunctionSymbolPropertyJs.symbols | 36 +++++++++++++ .../expandoFunctionSymbolPropertyJs.types | 38 +++++++++++++ .../compiler/expandoFunctionSymbolProperty.ts | 18 +++++++ .../expandoFunctionSymbolPropertyJs.ts | 26 +++++++++ 9 files changed, 285 insertions(+), 12 deletions(-) create mode 100644 tests/baselines/reference/expandoFunctionSymbolProperty.js create mode 100644 tests/baselines/reference/expandoFunctionSymbolProperty.symbols create mode 100644 tests/baselines/reference/expandoFunctionSymbolProperty.types create mode 100644 tests/baselines/reference/expandoFunctionSymbolPropertyJs.js create mode 100644 tests/baselines/reference/expandoFunctionSymbolPropertyJs.symbols create mode 100644 tests/baselines/reference/expandoFunctionSymbolPropertyJs.types create mode 100644 tests/cases/compiler/expandoFunctionSymbolProperty.ts create mode 100644 tests/cases/compiler/expandoFunctionSymbolPropertyJs.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 71b5dcde9c0..6ec408af5b0 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13072,19 +13072,16 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return; } // Combinations of function, class, enum and module - let members = emptySymbols; + let members = getExportsOfSymbol(symbol); let indexInfos: IndexInfo[] | undefined; - if (symbol.exports) { - members = getExportsOfSymbol(symbol); - if (symbol === globalThisSymbol) { - const varsOnly = new Map<__String, Symbol>(); - members.forEach(p => { - if (!(p.flags & SymbolFlags.BlockScoped) && !(p.flags & SymbolFlags.ValueModule && p.declarations?.length && every(p.declarations, isAmbientModule))) { - varsOnly.set(p.escapedName, p); - } - }); - members = varsOnly; - } + if (symbol === globalThisSymbol) { + const varsOnly = new Map<__String, Symbol>(); + members.forEach(p => { + if (!(p.flags & SymbolFlags.BlockScoped) && !(p.flags & SymbolFlags.ValueModule && p.declarations?.length && every(p.declarations, isAmbientModule))) { + varsOnly.set(p.escapedName, p); + } + }); + members = varsOnly; } let baseConstructorIndexInfo: IndexInfo | undefined; setStructuredTypeMembers(type, members, emptyArray, emptyArray, emptyArray); diff --git a/tests/baselines/reference/expandoFunctionSymbolProperty.js b/tests/baselines/reference/expandoFunctionSymbolProperty.js new file mode 100644 index 00000000000..db168306d03 --- /dev/null +++ b/tests/baselines/reference/expandoFunctionSymbolProperty.js @@ -0,0 +1,37 @@ +//// [tests/cases/compiler/expandoFunctionSymbolProperty.ts] //// + +//// [expandoFunctionSymbolProperty.ts] +// repro from https://github.com/microsoft/TypeScript/issues/54220 + +const symb = Symbol(); + +interface TestSymb { + (): void; + readonly [symb]: boolean; +} + +export function test(): TestSymb { + function inner() {} + inner[symb] = true; + return inner; +} + + +//// [expandoFunctionSymbolProperty.js] +// repro from https://github.com/microsoft/TypeScript/issues/54220 +const symb = Symbol(); +export function test() { + function inner() { } + inner[symb] = true; + return inner; +} + + +//// [expandoFunctionSymbolProperty.d.ts] +declare const symb: unique symbol; +interface TestSymb { + (): void; + readonly [symb]: boolean; +} +export declare function test(): TestSymb; +export {}; diff --git a/tests/baselines/reference/expandoFunctionSymbolProperty.symbols b/tests/baselines/reference/expandoFunctionSymbolProperty.symbols new file mode 100644 index 00000000000..1c05df6b8cf --- /dev/null +++ b/tests/baselines/reference/expandoFunctionSymbolProperty.symbols @@ -0,0 +1,33 @@ +//// [tests/cases/compiler/expandoFunctionSymbolProperty.ts] //// + +=== expandoFunctionSymbolProperty.ts === +// repro from https://github.com/microsoft/TypeScript/issues/54220 + +const symb = Symbol(); +>symb : Symbol(symb, Decl(expandoFunctionSymbolProperty.ts, 2, 5)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2019.symbol.d.ts, --, --)) + +interface TestSymb { +>TestSymb : Symbol(TestSymb, Decl(expandoFunctionSymbolProperty.ts, 2, 22)) + + (): void; + readonly [symb]: boolean; +>[symb] : Symbol(TestSymb[symb], Decl(expandoFunctionSymbolProperty.ts, 5, 11)) +>symb : Symbol(symb, Decl(expandoFunctionSymbolProperty.ts, 2, 5)) +} + +export function test(): TestSymb { +>test : Symbol(test, Decl(expandoFunctionSymbolProperty.ts, 7, 1)) +>TestSymb : Symbol(TestSymb, Decl(expandoFunctionSymbolProperty.ts, 2, 22)) + + function inner() {} +>inner : Symbol(inner, Decl(expandoFunctionSymbolProperty.ts, 9, 34)) + + inner[symb] = true; +>inner : Symbol(inner, Decl(expandoFunctionSymbolProperty.ts, 9, 34)) +>symb : Symbol(symb, Decl(expandoFunctionSymbolProperty.ts, 2, 5)) + + return inner; +>inner : Symbol(inner, Decl(expandoFunctionSymbolProperty.ts, 9, 34)) +} + diff --git a/tests/baselines/reference/expandoFunctionSymbolProperty.types b/tests/baselines/reference/expandoFunctionSymbolProperty.types new file mode 100644 index 00000000000..14a8bde19ef --- /dev/null +++ b/tests/baselines/reference/expandoFunctionSymbolProperty.types @@ -0,0 +1,34 @@ +//// [tests/cases/compiler/expandoFunctionSymbolProperty.ts] //// + +=== expandoFunctionSymbolProperty.ts === +// repro from https://github.com/microsoft/TypeScript/issues/54220 + +const symb = Symbol(); +>symb : unique symbol +>Symbol() : unique symbol +>Symbol : SymbolConstructor + +interface TestSymb { + (): void; + readonly [symb]: boolean; +>[symb] : boolean +>symb : unique symbol +} + +export function test(): TestSymb { +>test : () => TestSymb + + function inner() {} +>inner : { (): void; [symb]: boolean; } + + inner[symb] = true; +>inner[symb] = true : true +>inner[symb] : boolean +>inner : { (): void; [symb]: boolean; } +>symb : unique symbol +>true : true + + return inner; +>inner : { (): void; [symb]: boolean; } +} + diff --git a/tests/baselines/reference/expandoFunctionSymbolPropertyJs.js b/tests/baselines/reference/expandoFunctionSymbolPropertyJs.js new file mode 100644 index 00000000000..f5e1f53c08b --- /dev/null +++ b/tests/baselines/reference/expandoFunctionSymbolPropertyJs.js @@ -0,0 +1,54 @@ +//// [tests/cases/compiler/expandoFunctionSymbolPropertyJs.ts] //// + +//// [types.ts] +export const symb = Symbol(); + +export interface TestSymb { + (): void; + readonly [symb]: boolean; +} + +//// [a.js] +import { symb } from "./types"; + +/** + * @returns {import("./types").TestSymb} + */ +export function test() { + function inner() {} + inner[symb] = true; + return inner; +} + +//// [types.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.symb = void 0; +exports.symb = Symbol(); +//// [a.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.test = void 0; +var types_1 = require("./types"); +/** + * @returns {import("./types").TestSymb} + */ +function test() { + function inner() { } + inner[types_1.symb] = true; + return inner; +} +exports.test = test; + + +//// [types.d.ts] +export declare const symb: unique symbol; +export interface TestSymb { + (): void; + readonly [symb]: boolean; +} +//// [a.d.ts] +/** + * @returns {import("./types").TestSymb} + */ +export function test(): import("./types").TestSymb; diff --git a/tests/baselines/reference/expandoFunctionSymbolPropertyJs.symbols b/tests/baselines/reference/expandoFunctionSymbolPropertyJs.symbols new file mode 100644 index 00000000000..76c9a5378cf --- /dev/null +++ b/tests/baselines/reference/expandoFunctionSymbolPropertyJs.symbols @@ -0,0 +1,36 @@ +//// [tests/cases/compiler/expandoFunctionSymbolPropertyJs.ts] //// + +=== /types.ts === +export const symb = Symbol(); +>symb : Symbol(symb, Decl(types.ts, 0, 12)) +>Symbol : Symbol(Symbol, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.symbol.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2019.symbol.d.ts, --, --)) + +export interface TestSymb { +>TestSymb : Symbol(TestSymb, Decl(types.ts, 0, 29)) + + (): void; + readonly [symb]: boolean; +>[symb] : Symbol(TestSymb[symb], Decl(types.ts, 3, 11)) +>symb : Symbol(symb, Decl(types.ts, 0, 12)) +} + +=== /a.js === +import { symb } from "./types"; +>symb : Symbol(symb, Decl(a.js, 0, 8)) + +/** + * @returns {import("./types").TestSymb} + */ +export function test() { +>test : Symbol(test, Decl(a.js, 0, 31)) + + function inner() {} +>inner : Symbol(inner, Decl(a.js, 5, 24)) + + inner[symb] = true; +>inner : Symbol(inner, Decl(a.js, 5, 24)) +>symb : Symbol(symb, Decl(a.js, 0, 8)) + + return inner; +>inner : Symbol(inner, Decl(a.js, 5, 24)) +} diff --git a/tests/baselines/reference/expandoFunctionSymbolPropertyJs.types b/tests/baselines/reference/expandoFunctionSymbolPropertyJs.types new file mode 100644 index 00000000000..075ba65f2f5 --- /dev/null +++ b/tests/baselines/reference/expandoFunctionSymbolPropertyJs.types @@ -0,0 +1,38 @@ +//// [tests/cases/compiler/expandoFunctionSymbolPropertyJs.ts] //// + +=== /types.ts === +export const symb = Symbol(); +>symb : unique symbol +>Symbol() : unique symbol +>Symbol : SymbolConstructor + +export interface TestSymb { + (): void; + readonly [symb]: boolean; +>[symb] : boolean +>symb : unique symbol +} + +=== /a.js === +import { symb } from "./types"; +>symb : unique symbol + +/** + * @returns {import("./types").TestSymb} + */ +export function test() { +>test : () => import("./types").TestSymb + + function inner() {} +>inner : { (): void; [symb]: boolean; } + + inner[symb] = true; +>inner[symb] = true : true +>inner[symb] : boolean +>inner : { (): void; [symb]: boolean; } +>symb : unique symbol +>true : true + + return inner; +>inner : { (): void; [symb]: boolean; } +} diff --git a/tests/cases/compiler/expandoFunctionSymbolProperty.ts b/tests/cases/compiler/expandoFunctionSymbolProperty.ts new file mode 100644 index 00000000000..e0b38211574 --- /dev/null +++ b/tests/cases/compiler/expandoFunctionSymbolProperty.ts @@ -0,0 +1,18 @@ +// @strict: true +// @target: esnext +// @declaration: true + +// repro from https://github.com/microsoft/TypeScript/issues/54220 + +const symb = Symbol(); + +interface TestSymb { + (): void; + readonly [symb]: boolean; +} + +export function test(): TestSymb { + function inner() {} + inner[symb] = true; + return inner; +} diff --git a/tests/cases/compiler/expandoFunctionSymbolPropertyJs.ts b/tests/cases/compiler/expandoFunctionSymbolPropertyJs.ts new file mode 100644 index 00000000000..e04a19a60ff --- /dev/null +++ b/tests/cases/compiler/expandoFunctionSymbolPropertyJs.ts @@ -0,0 +1,26 @@ +// @strict: true +// @lib: esnext +// @allowJs: true +// @checkJs: true +// @declaration: true +// @outDir: dist + +// @filename: /types.ts +export const symb = Symbol(); + +export interface TestSymb { + (): void; + readonly [symb]: boolean; +} + +// @filename: /a.js +import { symb } from "./types"; + +/** + * @returns {import("./types").TestSymb} + */ +export function test() { + function inner() {} + inner[symb] = true; + return inner; +} \ No newline at end of file