Fixed expando functions with symbol-only properties (#54726)

This commit is contained in:
Mateusz Burzyński 2023-07-20 22:20:47 +02:00 committed by GitHub
parent 2623fe7049
commit 5128e06a9d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 285 additions and 12 deletions

View File

@ -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);

View File

@ -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 {};

View File

@ -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))
}

View File

@ -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; }
}

View File

@ -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;

View File

@ -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))
}

View File

@ -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; }
}

View File

@ -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;
}

View File

@ -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;
}