Allow references to the global Symbol in computed property names under isolatedDeclarations (#58771)

This commit is contained in:
Wesley Wigham 2024-06-04 12:55:24 -07:00 коммит произвёл GitHub
Родитель 506f3e26c3
Коммит 112e860602
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
7 изменённых файлов: 120 добавлений и 32 удалений

Просмотреть файл

@ -1511,6 +1511,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
Debug.assert(isExpressionNode(node));
return getSymbolAtLocation(node) === undefinedSymbol;
},
isDefinitelyReferenceToGlobalSymbolObject,
});
var evaluate = createEvaluator({
evaluateElementAccessExpression,
@ -2350,6 +2351,19 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
return checker;
function isDefinitelyReferenceToGlobalSymbolObject(node: Node): boolean {
if (!isPropertyAccessExpression(node)) return false;
if (!isIdentifier(node.name)) return false;
if (!isPropertyAccessExpression(node.expression) && !isIdentifier(node.expression)) return false;
if (isIdentifier(node.expression)) {
// Exactly `Symbol.something` and `Symbol` either does not resolve or definitely resolves to the global Symbol
return idText(node.expression) === "Symbol" && getResolvedSymbol(node.expression) === (getGlobalSymbol("Symbol" as __String, SymbolFlags.Value | SymbolFlags.ExportValue, /*diagnostic*/ undefined) || unknownSymbol);
}
if (!isIdentifier(node.expression.expression)) return false;
// Exactly `globalThis.Symbol.something` and `globalThis` resolves to the global `globalThis`
return idText(node.expression.name) === "Symbol" && idText(node.expression.expression) === "globalThis" && getResolvedSymbol(node.expression.expression) === globalThisSymbol;
}
function getCachedType(key: string | undefined) {
return key ? cachedTypes.get(key) : undefined;
}
@ -49738,6 +49752,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
return !sym.exports ? [] : nodeBuilder.symbolTableToDeclarationStatements(sym.exports, node, flags, tracker);
},
isImportRequiredByAugmentation,
isDefinitelyReferenceToGlobalSymbolObject,
};
function isImportRequiredByAugmentation(node: ImportDeclaration) {

Просмотреть файл

@ -1160,6 +1160,7 @@ export const notImplementedResolver: EmitResolver = {
isBindingCapturedByNode: notImplemented,
getDeclarationStatementsForSourceFile: notImplemented,
isImportRequiredByAugmentation: notImplemented,
isDefinitelyReferenceToGlobalSymbolObject: notImplemented,
};
const enum PipelinePhase {

Просмотреть файл

@ -350,7 +350,7 @@ export function createSyntacticTypeNodeBuilder(options: CompilerOptions, resolve
}
else if (prop.name.kind === SyntaxKind.ComputedPropertyName) {
const expression = prop.name.expression;
if (!isPrimitiveLiteralValue(expression, /*includeBigInt*/ false)) {
if (!isPrimitiveLiteralValue(expression, /*includeBigInt*/ false) && !resolver.isDefinitelyReferenceToGlobalSymbolObject(expression)) {
context.tracker.reportInferenceFallback(prop.name);
result = false;
}

Просмотреть файл

@ -1000,17 +1000,19 @@ export function transformDeclarations(context: TransformationContext) {
if (isolatedDeclarations) {
// Classes and object literals usually elide properties with computed names that are not of a literal type
// In isolated declarations TSC needs to error on these as we don't know the type in a DTE.
if (isClassDeclaration(input.parent) || isObjectLiteralExpression(input.parent)) {
context.addDiagnostic(createDiagnosticForNode(input, Diagnostics.Computed_property_names_on_class_or_object_literals_cannot_be_inferred_with_isolatedDeclarations));
return;
}
else if (
// Type declarations just need to double-check that the input computed name is an entity name expression
(isInterfaceDeclaration(input.parent) || isTypeLiteralNode(input.parent))
&& !isEntityNameExpression(input.name.expression)
) {
context.addDiagnostic(createDiagnosticForNode(input, Diagnostics.Computed_properties_must_be_number_or_string_literals_variables_or_dotted_expressions_with_isolatedDeclarations));
return;
if (!resolver.isDefinitelyReferenceToGlobalSymbolObject(input.name.expression)) {
if (isClassDeclaration(input.parent) || isObjectLiteralExpression(input.parent)) {
context.addDiagnostic(createDiagnosticForNode(input, Diagnostics.Computed_property_names_on_class_or_object_literals_cannot_be_inferred_with_isolatedDeclarations));
return;
}
else if (
// Type declarations just need to double-check that the input computed name is an entity name expression
(isInterfaceDeclaration(input.parent) || isTypeLiteralNode(input.parent))
&& !isEntityNameExpression(input.name.expression)
) {
context.addDiagnostic(createDiagnosticForNode(input, Diagnostics.Computed_properties_must_be_number_or_string_literals_variables_or_dotted_expressions_with_isolatedDeclarations));
return;
}
}
}
else if (!resolver.isLateBound(getParseTreeNode(input) as Declaration) || !isEntityNameExpression(input.name.expression)) {

Просмотреть файл

@ -5809,6 +5809,7 @@ export interface EmitResolver {
isBindingCapturedByNode(node: Node, decl: VariableDeclaration | BindingElement): boolean;
getDeclarationStatementsForSourceFile(node: SourceFile, flags: NodeBuilderFlags, tracker: SymbolTracker): Statement[] | undefined;
isImportRequiredByAugmentation(decl: ImportDeclaration): boolean;
isDefinitelyReferenceToGlobalSymbolObject(node: Node): boolean;
}
// dprint-ignore
@ -10334,4 +10335,5 @@ export interface SyntacticTypeNodeBuilderResolver {
getAllAccessorDeclarations(declaration: AccessorDeclaration): AllAccessorDeclarations;
isEntityNameVisible(entityName: EntityNameOrEntityNameExpression, enclosingDeclaration: Node, shouldComputeAliasToMakeVisible?: boolean): SymbolVisibilityResult;
requiresAddingImplicitUndefined(parameter: ParameterDeclaration | JSDocParameterTag): boolean;
isDefinitelyReferenceToGlobalSymbolObject(node: Node): boolean;
}

Просмотреть файл

@ -3,11 +3,16 @@ export namespace presentNs {
export const a = Symbol();
}
const aliasing = Symbol;
export type A = {
[missing]: number,
[ns.missing]: number,
[presentNs.a]: number,
[Symbol.iterator]: number,
[globalThis.Symbol.toStringTag]: number,
[(globalThis.Symbol).unscopables]: number,
[aliasing.isConcatSpreadable]: number,
[1]: number,
["2"]: number,
[(missing2)]: number,
@ -19,6 +24,9 @@ export interface B {
[ns.missing]: number,
[presentNs.a]: number,
[Symbol.iterator]: number,
[globalThis.Symbol.toStringTag]: number,
[(globalThis.Symbol).unscopables]: number,
[aliasing.isConcatSpreadable]: number,
[1]: number,
["2"]: number,
[(missing2)]: number,
@ -30,6 +38,9 @@ export class C {
[ns.missing]: number = 1;
[presentNs.a]: number = 1;
[Symbol.iterator]: number = 1;
[globalThis.Symbol.toStringTag]: number = 1;
[(globalThis.Symbol).unscopables]: number = 1;
[aliasing.isConcatSpreadable]: number = 1;
[1]: number = 1;
["2"]: number = 1;
[(missing2)]: number = 1;
@ -41,6 +52,9 @@ export const D = {
[ns.missing]: 1,
[presentNs.a]: 1,
[Symbol.iterator]: 1,
[globalThis.Symbol.toStringTag]: 1,
[(globalThis.Symbol).unscopables]: 1,
[aliasing.isConcatSpreadable]: 1,
[1]: 1,
["2"]: 1,
[(missing2)]: 1,
@ -50,11 +64,14 @@ export const D = {
export declare namespace presentNs {
const a: unique symbol;
}
declare const aliasing: SymbolConstructor;
export type A = {
[missing]: number;
[ns.missing]: number;
[presentNs.a]: number;
[Symbol.iterator]: number;
[globalThis.Symbol.toStringTag]: number;
[aliasing.isConcatSpreadable]: number;
[1]: number;
["2"]: number;
};
@ -63,10 +80,14 @@ export interface B {
[ns.missing]: number;
[presentNs.a]: number;
[Symbol.iterator]: number;
[globalThis.Symbol.toStringTag]: number;
[aliasing.isConcatSpreadable]: number;
[1]: number;
["2"]: number;
}
export declare class C {
[Symbol.iterator]: number;
[globalThis.Symbol.toStringTag]: number;
[1]: number;
["2"]: number;
}
@ -74,32 +95,39 @@ export declare const D: {
[x: string]: number;
[x: number]: number;
[presentNs.a]: number;
[aliasing.toStringTag]: number;
1: number;
"2": number;
};
export {};
//// [Diagnostics reported]
declarationComputedPropertyNames.ts(2,18): error TS9010: Variable must have an explicit type annotation with --isolatedDeclarations.
declarationComputedPropertyNames.ts(12,5): error TS9014: Computed properties must be number or string literals, variables or dotted expressions with --isolatedDeclarations.
declarationComputedPropertyNames.ts(5,7): error TS9010: Variable must have an explicit type annotation with --isolatedDeclarations.
declarationComputedPropertyNames.ts(13,5): error TS9014: Computed properties must be number or string literals, variables or dotted expressions with --isolatedDeclarations.
declarationComputedPropertyNames.ts(23,5): error TS9014: Computed properties must be number or string literals, variables or dotted expressions with --isolatedDeclarations.
declarationComputedPropertyNames.ts(24,5): error TS9014: Computed properties must be number or string literals, variables or dotted expressions with --isolatedDeclarations.
declarationComputedPropertyNames.ts(28,5): error TS9038: Computed property names on class or object literals cannot be inferred with --isolatedDeclarations.
declarationComputedPropertyNames.ts(29,5): error TS9038: Computed property names on class or object literals cannot be inferred with --isolatedDeclarations.
declarationComputedPropertyNames.ts(30,5): error TS9038: Computed property names on class or object literals cannot be inferred with --isolatedDeclarations.
declarationComputedPropertyNames.ts(31,5): error TS9038: Computed property names on class or object literals cannot be inferred with --isolatedDeclarations.
declarationComputedPropertyNames.ts(34,5): error TS9038: Computed property names on class or object literals cannot be inferred with --isolatedDeclarations.
declarationComputedPropertyNames.ts(35,5): error TS9038: Computed property names on class or object literals cannot be inferred with --isolatedDeclarations.
declarationComputedPropertyNames.ts(39,5): error TS9038: Computed property names on class or object literals cannot be inferred with --isolatedDeclarations.
declarationComputedPropertyNames.ts(40,5): error TS9038: Computed property names on class or object literals cannot be inferred with --isolatedDeclarations.
declarationComputedPropertyNames.ts(17,5): error TS9014: Computed properties must be number or string literals, variables or dotted expressions with --isolatedDeclarations.
declarationComputedPropertyNames.ts(18,5): error TS9014: Computed properties must be number or string literals, variables or dotted expressions with --isolatedDeclarations.
declarationComputedPropertyNames.ts(27,5): error TS9014: Computed properties must be number or string literals, variables or dotted expressions with --isolatedDeclarations.
declarationComputedPropertyNames.ts(31,5): error TS9014: Computed properties must be number or string literals, variables or dotted expressions with --isolatedDeclarations.
declarationComputedPropertyNames.ts(32,5): error TS9014: Computed properties must be number or string literals, variables or dotted expressions with --isolatedDeclarations.
declarationComputedPropertyNames.ts(36,5): error TS9038: Computed property names on class or object literals cannot be inferred with --isolatedDeclarations.
declarationComputedPropertyNames.ts(37,5): error TS9038: Computed property names on class or object literals cannot be inferred with --isolatedDeclarations.
declarationComputedPropertyNames.ts(38,5): error TS9038: Computed property names on class or object literals cannot be inferred with --isolatedDeclarations.
declarationComputedPropertyNames.ts(41,5): error TS9038: Computed property names on class or object literals cannot be inferred with --isolatedDeclarations.
declarationComputedPropertyNames.ts(42,5): error TS9038: Computed property names on class or object literals cannot be inferred with --isolatedDeclarations.
declarationComputedPropertyNames.ts(45,5): error TS9038: Computed property names on class or object literals cannot be inferred with --isolatedDeclarations.
declarationComputedPropertyNames.ts(46,5): error TS9038: Computed property names on class or object literals cannot be inferred with --isolatedDeclarations.
declarationComputedPropertyNames.ts(50,5): error TS9038: Computed property names on class or object literals cannot be inferred with --isolatedDeclarations.
declarationComputedPropertyNames.ts(51,5): error TS9038: Computed property names on class or object literals cannot be inferred with --isolatedDeclarations.
declarationComputedPropertyNames.ts(52,5): error TS9038: Computed property names on class or object literals cannot be inferred with --isolatedDeclarations.
declarationComputedPropertyNames.ts(55,5): error TS9038: Computed property names on class or object literals cannot be inferred with --isolatedDeclarations.
declarationComputedPropertyNames.ts(56,5): error TS9038: Computed property names on class or object literals cannot be inferred with --isolatedDeclarations.
declarationComputedPropertyNames.ts(59,5): error TS9038: Computed property names on class or object literals cannot be inferred with --isolatedDeclarations.
declarationComputedPropertyNames.ts(60,5): error TS9038: Computed property names on class or object literals cannot be inferred with --isolatedDeclarations.
==== declarationComputedPropertyNames.ts (17 errors) ====
==== declarationComputedPropertyNames.ts (22 errors) ====
export namespace presentNs {
export const a = Symbol();
~
@ -107,11 +135,21 @@ declarationComputedPropertyNames.ts(46,5): error TS9038: Computed property names
!!! related TS9027 declarationComputedPropertyNames.ts:2:18: Add a type annotation to the variable a.
}
const aliasing = Symbol;
~~~~~~~~
!!! error TS9010: Variable must have an explicit type annotation with --isolatedDeclarations.
!!! related TS9027 declarationComputedPropertyNames.ts:5:7: Add a type annotation to the variable aliasing.
export type A = {
[missing]: number,
[ns.missing]: number,
[presentNs.a]: number,
[Symbol.iterator]: number,
[globalThis.Symbol.toStringTag]: number,
[(globalThis.Symbol).unscopables]: number,
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS9014: Computed properties must be number or string literals, variables or dotted expressions with --isolatedDeclarations.
[aliasing.isConcatSpreadable]: number,
[1]: number,
["2"]: number,
[(missing2)]: number,
@ -127,6 +165,11 @@ declarationComputedPropertyNames.ts(46,5): error TS9038: Computed property names
[ns.missing]: number,
[presentNs.a]: number,
[Symbol.iterator]: number,
[globalThis.Symbol.toStringTag]: number,
[(globalThis.Symbol).unscopables]: number,
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS9014: Computed properties must be number or string literals, variables or dotted expressions with --isolatedDeclarations.
[aliasing.isConcatSpreadable]: number,
[1]: number,
["2"]: number,
[(missing2)]: number,
@ -148,7 +191,12 @@ declarationComputedPropertyNames.ts(46,5): error TS9038: Computed property names
~~~~~~~~~~~~~
!!! error TS9038: Computed property names on class or object literals cannot be inferred with --isolatedDeclarations.
[Symbol.iterator]: number = 1;
~~~~~~~~~~~~~~~~~
[globalThis.Symbol.toStringTag]: number = 1;
[(globalThis.Symbol).unscopables]: number = 1;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS9038: Computed property names on class or object literals cannot be inferred with --isolatedDeclarations.
[aliasing.isConcatSpreadable]: number = 1;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS9038: Computed property names on class or object literals cannot be inferred with --isolatedDeclarations.
[1]: number = 1;
["2"]: number = 1;
@ -164,28 +212,34 @@ declarationComputedPropertyNames.ts(46,5): error TS9038: Computed property names
[missing]: 1,
~~~~~~~~~
!!! error TS9038: Computed property names on class or object literals cannot be inferred with --isolatedDeclarations.
!!! related TS9027 declarationComputedPropertyNames.ts:38:14: Add a type annotation to the variable D.
!!! related TS9027 declarationComputedPropertyNames.ts:49:14: Add a type annotation to the variable D.
[ns.missing]: 1,
~~~~~~~~~~~~
!!! error TS9038: Computed property names on class or object literals cannot be inferred with --isolatedDeclarations.
!!! related TS9027 declarationComputedPropertyNames.ts:38:14: Add a type annotation to the variable D.
!!! related TS9027 declarationComputedPropertyNames.ts:49:14: Add a type annotation to the variable D.
[presentNs.a]: 1,
~~~~~~~~~~~~~
!!! error TS9038: Computed property names on class or object literals cannot be inferred with --isolatedDeclarations.
!!! related TS9027 declarationComputedPropertyNames.ts:38:14: Add a type annotation to the variable D.
!!! related TS9027 declarationComputedPropertyNames.ts:49:14: Add a type annotation to the variable D.
[Symbol.iterator]: 1,
~~~~~~~~~~~~~~~~~
[globalThis.Symbol.toStringTag]: 1,
[(globalThis.Symbol).unscopables]: 1,
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS9038: Computed property names on class or object literals cannot be inferred with --isolatedDeclarations.
!!! related TS9027 declarationComputedPropertyNames.ts:38:14: Add a type annotation to the variable D.
!!! related TS9027 declarationComputedPropertyNames.ts:49:14: Add a type annotation to the variable D.
[aliasing.isConcatSpreadable]: 1,
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS9038: Computed property names on class or object literals cannot be inferred with --isolatedDeclarations.
!!! related TS9027 declarationComputedPropertyNames.ts:49:14: Add a type annotation to the variable D.
[1]: 1,
["2"]: 1,
[(missing2)]: 1,
~~~~~~~~~~~~
!!! error TS9038: Computed property names on class or object literals cannot be inferred with --isolatedDeclarations.
!!! related TS9027 declarationComputedPropertyNames.ts:38:14: Add a type annotation to the variable D.
!!! related TS9027 declarationComputedPropertyNames.ts:49:14: Add a type annotation to the variable D.
[Math.random() > 0.5 ? "f1" : "f2"]: 1,
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS9038: Computed property names on class or object literals cannot be inferred with --isolatedDeclarations.
!!! related TS9027 declarationComputedPropertyNames.ts:38:14: Add a type annotation to the variable D.
!!! related TS9027 declarationComputedPropertyNames.ts:49:14: Add a type annotation to the variable D.
};

Просмотреть файл

@ -6,11 +6,16 @@ export namespace presentNs {
export const a = Symbol();
}
const aliasing = Symbol;
export type A = {
[missing]: number,
[ns.missing]: number,
[presentNs.a]: number,
[Symbol.iterator]: number,
[globalThis.Symbol.toStringTag]: number,
[(globalThis.Symbol).unscopables]: number,
[aliasing.isConcatSpreadable]: number,
[1]: number,
["2"]: number,
[(missing2)]: number,
@ -22,6 +27,9 @@ export interface B {
[ns.missing]: number,
[presentNs.a]: number,
[Symbol.iterator]: number,
[globalThis.Symbol.toStringTag]: number,
[(globalThis.Symbol).unscopables]: number,
[aliasing.isConcatSpreadable]: number,
[1]: number,
["2"]: number,
[(missing2)]: number,
@ -33,6 +41,9 @@ export class C {
[ns.missing]: number = 1;
[presentNs.a]: number = 1;
[Symbol.iterator]: number = 1;
[globalThis.Symbol.toStringTag]: number = 1;
[(globalThis.Symbol).unscopables]: number = 1;
[aliasing.isConcatSpreadable]: number = 1;
[1]: number = 1;
["2"]: number = 1;
[(missing2)]: number = 1;
@ -44,6 +55,9 @@ export const D = {
[ns.missing]: 1,
[presentNs.a]: 1,
[Symbol.iterator]: 1,
[globalThis.Symbol.toStringTag]: 1,
[(globalThis.Symbol).unscopables]: 1,
[aliasing.isConcatSpreadable]: 1,
[1]: 1,
["2"]: 1,
[(missing2)]: 1,