From 2ab21a831724e13dbc5c71d3e45776d0b5761cba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Fri, 18 Aug 2023 00:34:33 +0200 Subject: [PATCH] Disallow object prototype property access on const enums --- src/compiler/checker.ts | 2 +- ...NoObjectPrototypePropertyAccess.errors.txt | 36 ++++++++++ ...numNoObjectPrototypePropertyAccess.symbols | 50 +++++++++++++ ...tEnumNoObjectPrototypePropertyAccess.types | 71 +++++++++++++++++++ ...onstEnumNoObjectPrototypePropertyAccess.ts | 14 ++++ 5 files changed, 172 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/constEnumNoObjectPrototypePropertyAccess.errors.txt create mode 100644 tests/baselines/reference/constEnumNoObjectPrototypePropertyAccess.symbols create mode 100644 tests/baselines/reference/constEnumNoObjectPrototypePropertyAccess.types create mode 100644 tests/cases/conformance/constEnums/constEnumNoObjectPrototypePropertyAccess.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c9809acc781c2..0590b3060653b 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -32046,7 +32046,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } return isErrorType(apparentType) ? errorType : apparentType; } - prop = getPropertyOfType(apparentType, right.escapedText, /*skipObjectFunctionPropertyAugment*/ false, /*includeTypeOnlyMembers*/ node.kind === SyntaxKind.QualifiedName); + prop = getPropertyOfType(apparentType, right.escapedText, /*skipObjectFunctionPropertyAugment*/ isConstEnumObjectType(apparentType), /*includeTypeOnlyMembers*/ node.kind === SyntaxKind.QualifiedName); } // In `Foo.Bar.Baz`, 'Foo' is not referenced if 'Bar' is a const enum or a module containing only const enums. // `Foo` is also not referenced in `enum FooCopy { Bar = Foo.Bar }`, because the enum member value gets inlined diff --git a/tests/baselines/reference/constEnumNoObjectPrototypePropertyAccess.errors.txt b/tests/baselines/reference/constEnumNoObjectPrototypePropertyAccess.errors.txt new file mode 100644 index 0000000000000..ffc10079bb16b --- /dev/null +++ b/tests/baselines/reference/constEnumNoObjectPrototypePropertyAccess.errors.txt @@ -0,0 +1,36 @@ +constEnumNoObjectPrototypePropertyAccess.ts(5,19): error TS2339: Property 'constructor' does not exist on type 'typeof Bebra'. +constEnumNoObjectPrototypePropertyAccess.ts(6,19): error TS2339: Property 'hasOwnProperty' does not exist on type 'typeof Bebra'. +constEnumNoObjectPrototypePropertyAccess.ts(7,19): error TS2339: Property 'isPrototypeOf' does not exist on type 'typeof Bebra'. +constEnumNoObjectPrototypePropertyAccess.ts(8,19): error TS2339: Property 'propertyIsEnumerable' does not exist on type 'typeof Bebra'. +constEnumNoObjectPrototypePropertyAccess.ts(9,19): error TS2339: Property 'toLocaleString' does not exist on type 'typeof Bebra'. +constEnumNoObjectPrototypePropertyAccess.ts(10,19): error TS2339: Property 'toString' does not exist on type 'typeof Bebra'. +constEnumNoObjectPrototypePropertyAccess.ts(11,19): error TS2339: Property 'valueOf' does not exist on type 'typeof Bebra'. + + +==== constEnumNoObjectPrototypePropertyAccess.ts (7 errors) ==== + // https://github.com/microsoft/TypeScript/issues/55421 + + const enum Bebra {} + + console.log(Bebra.constructor) + ~~~~~~~~~~~ +!!! error TS2339: Property 'constructor' does not exist on type 'typeof Bebra'. + console.log(Bebra.hasOwnProperty) + ~~~~~~~~~~~~~~ +!!! error TS2339: Property 'hasOwnProperty' does not exist on type 'typeof Bebra'. + console.log(Bebra.isPrototypeOf) + ~~~~~~~~~~~~~ +!!! error TS2339: Property 'isPrototypeOf' does not exist on type 'typeof Bebra'. + console.log(Bebra.propertyIsEnumerable) + ~~~~~~~~~~~~~~~~~~~~ +!!! error TS2339: Property 'propertyIsEnumerable' does not exist on type 'typeof Bebra'. + console.log(Bebra.toLocaleString) + ~~~~~~~~~~~~~~ +!!! error TS2339: Property 'toLocaleString' does not exist on type 'typeof Bebra'. + console.log(Bebra.toString) + ~~~~~~~~ +!!! error TS2339: Property 'toString' does not exist on type 'typeof Bebra'. + console.log(Bebra.valueOf) + ~~~~~~~ +!!! error TS2339: Property 'valueOf' does not exist on type 'typeof Bebra'. + \ No newline at end of file diff --git a/tests/baselines/reference/constEnumNoObjectPrototypePropertyAccess.symbols b/tests/baselines/reference/constEnumNoObjectPrototypePropertyAccess.symbols new file mode 100644 index 0000000000000..c018043eab648 --- /dev/null +++ b/tests/baselines/reference/constEnumNoObjectPrototypePropertyAccess.symbols @@ -0,0 +1,50 @@ +//// [tests/cases/conformance/constEnums/constEnumNoObjectPrototypePropertyAccess.ts] //// + +=== constEnumNoObjectPrototypePropertyAccess.ts === +// https://github.com/microsoft/TypeScript/issues/55421 + +const enum Bebra {} +>Bebra : Symbol(Bebra, Decl(constEnumNoObjectPrototypePropertyAccess.ts, 0, 0)) + +console.log(Bebra.constructor) +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>Bebra : Symbol(Bebra, Decl(constEnumNoObjectPrototypePropertyAccess.ts, 0, 0)) + +console.log(Bebra.hasOwnProperty) +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>Bebra : Symbol(Bebra, Decl(constEnumNoObjectPrototypePropertyAccess.ts, 0, 0)) + +console.log(Bebra.isPrototypeOf) +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>Bebra : Symbol(Bebra, Decl(constEnumNoObjectPrototypePropertyAccess.ts, 0, 0)) + +console.log(Bebra.propertyIsEnumerable) +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>Bebra : Symbol(Bebra, Decl(constEnumNoObjectPrototypePropertyAccess.ts, 0, 0)) + +console.log(Bebra.toLocaleString) +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>Bebra : Symbol(Bebra, Decl(constEnumNoObjectPrototypePropertyAccess.ts, 0, 0)) + +console.log(Bebra.toString) +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>Bebra : Symbol(Bebra, Decl(constEnumNoObjectPrototypePropertyAccess.ts, 0, 0)) + +console.log(Bebra.valueOf) +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>Bebra : Symbol(Bebra, Decl(constEnumNoObjectPrototypePropertyAccess.ts, 0, 0)) + diff --git a/tests/baselines/reference/constEnumNoObjectPrototypePropertyAccess.types b/tests/baselines/reference/constEnumNoObjectPrototypePropertyAccess.types new file mode 100644 index 0000000000000..565faf535ad44 --- /dev/null +++ b/tests/baselines/reference/constEnumNoObjectPrototypePropertyAccess.types @@ -0,0 +1,71 @@ +//// [tests/cases/conformance/constEnums/constEnumNoObjectPrototypePropertyAccess.ts] //// + +=== constEnumNoObjectPrototypePropertyAccess.ts === +// https://github.com/microsoft/TypeScript/issues/55421 + +const enum Bebra {} +>Bebra : Bebra + +console.log(Bebra.constructor) +>console.log(Bebra.constructor) : void +>console.log : (...data: any[]) => void +>console : Console +>log : (...data: any[]) => void +>Bebra.constructor : any +>Bebra : typeof Bebra +>constructor : any + +console.log(Bebra.hasOwnProperty) +>console.log(Bebra.hasOwnProperty) : void +>console.log : (...data: any[]) => void +>console : Console +>log : (...data: any[]) => void +>Bebra.hasOwnProperty : any +>Bebra : typeof Bebra +>hasOwnProperty : any + +console.log(Bebra.isPrototypeOf) +>console.log(Bebra.isPrototypeOf) : void +>console.log : (...data: any[]) => void +>console : Console +>log : (...data: any[]) => void +>Bebra.isPrototypeOf : any +>Bebra : typeof Bebra +>isPrototypeOf : any + +console.log(Bebra.propertyIsEnumerable) +>console.log(Bebra.propertyIsEnumerable) : void +>console.log : (...data: any[]) => void +>console : Console +>log : (...data: any[]) => void +>Bebra.propertyIsEnumerable : any +>Bebra : typeof Bebra +>propertyIsEnumerable : any + +console.log(Bebra.toLocaleString) +>console.log(Bebra.toLocaleString) : void +>console.log : (...data: any[]) => void +>console : Console +>log : (...data: any[]) => void +>Bebra.toLocaleString : any +>Bebra : typeof Bebra +>toLocaleString : any + +console.log(Bebra.toString) +>console.log(Bebra.toString) : void +>console.log : (...data: any[]) => void +>console : Console +>log : (...data: any[]) => void +>Bebra.toString : any +>Bebra : typeof Bebra +>toString : any + +console.log(Bebra.valueOf) +>console.log(Bebra.valueOf) : void +>console.log : (...data: any[]) => void +>console : Console +>log : (...data: any[]) => void +>Bebra.valueOf : any +>Bebra : typeof Bebra +>valueOf : any + diff --git a/tests/cases/conformance/constEnums/constEnumNoObjectPrototypePropertyAccess.ts b/tests/cases/conformance/constEnums/constEnumNoObjectPrototypePropertyAccess.ts new file mode 100644 index 0000000000000..0f8e59b61afd3 --- /dev/null +++ b/tests/cases/conformance/constEnums/constEnumNoObjectPrototypePropertyAccess.ts @@ -0,0 +1,14 @@ +// @strict: true +// @noEmit: true + +// https://github.com/microsoft/TypeScript/issues/55421 + +const enum Bebra {} + +console.log(Bebra.constructor) +console.log(Bebra.hasOwnProperty) +console.log(Bebra.isPrototypeOf) +console.log(Bebra.propertyIsEnumerable) +console.log(Bebra.toLocaleString) +console.log(Bebra.toString) +console.log(Bebra.valueOf)