Skip to content

Commit 969a4b0

Browse files
committed
Private Name Support in the Checker (#5)
- [x] treat private names as unique: - case 1: cannot say that a variable is of a class type unless the variable points to an instance of the class - see [test](https://github.com/mheiber/TypeScript/tree/checker/tests/cases/conformance/classes/members/privateNames/privateNamesUnique.ts) - case 2: private names in class hierarchies do not conflict - see [test](https://github.com/mheiber/TypeScript/tree/checker/tests/cases/conformance/classes/members/privateNames/privateNamesNoConflictWhenInheriting.ts) - [x] `#constructor` is reserved - see [test](https://github.com/mheiber/TypeScript/tree/checker/tests/cases/conformance/classes/members/privateNames/privateNameConstructorReserved.ts) - check in `bindWorker`, where every node is visited - [x] Accessibility modifiers can't be used with private names - see [test](https://github.com/mheiber/TypeScript/tree/checker/tests/cases/conformance/classes/members/privateNames/privateNamesNoAccessibilityModifiers.ts) - implemented in `checkAccessibilityModifiers`, using `ModifierFlags.AccessibilityModifier` - [x] `delete #foo` not allowed - [x] Private name accesses not allowed outside of the defining class - see test: https://github.com/mheiber/TypeScript/tree/checker/tests/cases/conformance/classes/members/privateNames/privateNameNotAccessibleOutsideDefiningClass.ts - see [test](https://github.com/mheiber/TypeScript/tree/checker/tests/cases/conformance/classes/members/privateNames/privateNamesNoDelete.ts) - implemented in `checkDeleteExpression` - [x] Do [the right thing](https://gist.github.com/mheiber/b6fc7adb426c2e1cdaceb5d7786fc630) for nested classes mv private name tests together more checker tests for private names update naming and cleanup for check private names for private name support in the checker: - make names more consistent - remove unnecessary checks - add utility function to public API - other small cleanup Move getPropertyNameForUniqueESSymbol to utility for consistency with other calculation of special property names (starting with __), move the calculation of property names for unique es symbols to `utilities.ts`. private name tests strict+es6 Update private name tests to use 'strict' type checking and to target es6 instead of default. Makes the js output easier to read and tests more surface area with other checker features. error message for private names in obj literals Disallow decorating private-named properties because the spec is still in flux. Signed-off-by: Max Heiber <[email protected]>
1 parent 2ca8ad3 commit 969a4b0

File tree

135 files changed

+3482
-78
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

135 files changed

+3482
-78
lines changed

src/compiler/binder.ts

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,16 @@ namespace ts {
359359
if (isWellKnownSymbolSyntactically(name)) {
360360
return getPropertyNameForKnownSymbolName(idText(name.name));
361361
}
362+
if (isPrivateName(name)) {
363+
// containingClass exists because private names only allowed inside classes
364+
const containingClass = getContainingClass(name.parent);
365+
if (!containingClass) {
366+
// we're in a case where there's a private name outside a class (invalid)
367+
return undefined;
368+
}
369+
const containingClassSymbol = containingClass.symbol;
370+
return getPropertyNameForPrivateNameDescription(containingClassSymbol, name.escapedText);
371+
}
362372
return isPropertyNameLiteral(name) ? getEscapedTextOfIdentifierOrLiteral(name) : undefined;
363373
}
364374
switch (node.kind) {
@@ -415,6 +425,10 @@ namespace ts {
415425

416426
const isDefaultExport = hasModifier(node, ModifierFlags.Default);
417427

428+
// need this before getDeclarationName
429+
if (isNamedDeclaration(node)) {
430+
node.name.parent = node;
431+
}
418432
// The exported symbol for an export default function/class node is always named "default"
419433
const name = isDefaultExport && parent ? InternalSymbolName.Default : getDeclarationName(node);
420434

@@ -467,11 +481,6 @@ namespace ts {
467481
symbolTable.set(name, symbol = createSymbol(SymbolFlags.None, name));
468482
}
469483
else if (!(includes & SymbolFlags.Variable && symbol.flags & SymbolFlags.Assignment)) {
470-
// Assignment declarations are allowed to merge with variables, no matter what other flags they have.
471-
if (isNamedDeclaration(node)) {
472-
node.name.parent = node;
473-
}
474-
475484
// Report errors every position with duplicate declaration
476485
// Report errors on previous encountered declarations
477486
let message = symbol.flags & SymbolFlags.BlockScopedVariable
@@ -2026,6 +2035,18 @@ namespace ts {
20262035
return Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode;
20272036
}
20282037

2038+
// The binder visits every node, so this is a good place to check for
2039+
// the reserved private name (there is only one)
2040+
function checkPrivateName(node: PrivateName) {
2041+
if (node.escapedText === "#constructor") {
2042+
// Report error only if there are no parse errors in file
2043+
if (!file.parseDiagnostics.length) {
2044+
file.bindDiagnostics.push(createDiagnosticForNode(node,
2045+
Diagnostics.constructor_is_a_reserved_word, declarationNameToString(node)));
2046+
}
2047+
}
2048+
}
2049+
20292050
function checkStrictModeBinaryExpression(node: BinaryExpression) {
20302051
if (inStrictMode && isLeftHandSideExpression(node.left) && isAssignmentOperator(node.operatorToken.kind)) {
20312052
// ECMA 262 (Annex C) The identifier eval or arguments may not appear as the LeftHandSideExpression of an
@@ -2298,6 +2319,8 @@ namespace ts {
22982319
node.flowNode = currentFlow;
22992320
}
23002321
return checkStrictModeIdentifier(<Identifier>node);
2322+
case SyntaxKind.PrivateName:
2323+
return checkPrivateName(node as PrivateName);
23012324
case SyntaxKind.PropertyAccessExpression:
23022325
case SyntaxKind.ElementAccessExpression:
23032326
const expr = node as PropertyAccessExpression | ElementAccessExpression;

src/compiler/checker.ts

Lines changed: 108 additions & 26 deletions
Large diffs are not rendered by default.

src/compiler/diagnosticMessages.json

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5361,6 +5361,37 @@
53615361
"'#!' can only be used at the start of a file.": {
53625362
"category": "Error",
53635363
"code": 18008
5364+
},
5365+
"Private names cannot be used as parameters": {
5366+
"category": "Error",
5367+
"code": 18009
5368+
},
5369+
"Accessibility modifiers cannot be used with private names.": {
5370+
"category": "Error",
5371+
"code": 18010
5372+
},
5373+
"The operand of a delete operator cannot be a private name.": {
5374+
"category": "Error",
5375+
"code": 18011
5376+
},
5377+
"'#constructor' is a reserved word.": {
5378+
"category": "Error",
5379+
"code": 18012
5380+
},
5381+
"Property '{0}' is not accessible outside class '{1}' because it has a private name.": {
5382+
"category": "Error",
5383+
"code": 18013
5384+
},
5385+
"This usage of '{0}' refers to the private member declared in its enclosing class. While type '{1}' has a private member with the same spelling, its declaration and accessibility are distinct.": {
5386+
"category": "Error",
5387+
"code": 18014
5388+
},
5389+
"Property '{0}' is missing in type '{1}'. While type '{1}' has a private member with the same spelling, its declaration and accessibility are distinct.": {
5390+
"category": "Error",
5391+
"code": 18015
5392+
},
5393+
"Private names are not allowed outside class bodies.": {
5394+
"category": "Error",
5395+
"code": 18016
53645396
}
5365-
53665397
}

src/compiler/transformers/es5.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,10 @@ namespace ts {
8282
* @param node A PropertyAccessExpression
8383
*/
8484
function substitutePropertyAccessExpression(node: PropertyAccessExpression): Expression {
85-
const literalName = trySubstituteReservedName(cast(node.name, isIdentifier));
85+
if (isPrivateName(node.name)) {
86+
return node;
87+
}
88+
const literalName = trySubstituteReservedName(node.name);
8689
if (literalName) {
8790
return setTextRange(createElementAccess(node.expression, literalName), node);
8891
}

src/compiler/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3347,6 +3347,7 @@ namespace ts {
33473347
getDeclaredTypeOfSymbol(symbol: Symbol): Type;
33483348
getPropertiesOfType(type: Type): Symbol[];
33493349
getPropertyOfType(type: Type, propertyName: string): Symbol | undefined;
3350+
getPropertyForPrivateName(apparentType: Type, leftType: Type, right: PrivateName, errorNode: Node | undefined): Symbol | undefined;
33503351
/* @internal */ getTypeOfPropertyOfType(type: Type, propertyName: string): Type | undefined;
33513352
getIndexInfoOfType(type: Type, kind: IndexKind): IndexInfo | undefined;
33523353
getSignaturesOfType(type: Type, kind: SignatureKind): readonly Signature[];

src/compiler/utilities.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1584,6 +1584,10 @@ namespace ts {
15841584
export function nodeCanBeDecorated(node: ClassElement, parent: Node): boolean;
15851585
export function nodeCanBeDecorated(node: Node, parent: Node, grandparent: Node): boolean;
15861586
export function nodeCanBeDecorated(node: Node, parent?: Node, grandparent?: Node): boolean {
1587+
// private names cannot be used with decorators yet
1588+
if (isNamedDeclaration(node) && isPrivateName(node.name)) {
1589+
return false;
1590+
}
15871591
switch (node.kind) {
15881592
case SyntaxKind.ClassDeclaration:
15891593
// classes are valid targets
@@ -2964,10 +2968,18 @@ namespace ts {
29642968
}
29652969
}
29662970

2971+
export function getPropertyNameForUniqueESSymbol(symbol: Symbol): __String {
2972+
return `__@${getSymbolId(symbol)}@${symbol.escapedName}` as __String;
2973+
}
2974+
29672975
export function getPropertyNameForKnownSymbolName(symbolName: string): __String {
29682976
return "__@" + symbolName as __String;
29692977
}
29702978

2979+
export function getPropertyNameForPrivateNameDescription(containingClassSymbol: Symbol, description: __String): __String {
2980+
return `__#${getSymbolId(containingClassSymbol)}@${description}` as __String;
2981+
}
2982+
29712983
export function isKnownSymbol(symbol: Symbol): boolean {
29722984
return startsWith(symbol.escapedName as string, "__@");
29732985
}

tests/baselines/reference/api/tsserverlibrary.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2009,6 +2009,7 @@ declare namespace ts {
20092009
getDeclaredTypeOfSymbol(symbol: Symbol): Type;
20102010
getPropertiesOfType(type: Type): Symbol[];
20112011
getPropertyOfType(type: Type, propertyName: string): Symbol | undefined;
2012+
getPropertyForPrivateName(apparentType: Type, leftType: Type, right: PrivateName, errorNode: Node | undefined): Symbol | undefined;
20122013
getIndexInfoOfType(type: Type, kind: IndexKind): IndexInfo | undefined;
20132014
getSignaturesOfType(type: Type, kind: SignatureKind): readonly Signature[];
20142015
getIndexTypeOfType(type: Type, kind: IndexKind): Type | undefined;

tests/baselines/reference/api/typescript.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2009,6 +2009,7 @@ declare namespace ts {
20092009
getDeclaredTypeOfSymbol(symbol: Symbol): Type;
20102010
getPropertiesOfType(type: Type): Symbol[];
20112011
getPropertyOfType(type: Type, propertyName: string): Symbol | undefined;
2012+
getPropertyForPrivateName(apparentType: Type, leftType: Type, right: PrivateName, errorNode: Node | undefined): Symbol | undefined;
20122013
getIndexInfoOfType(type: Type, kind: IndexKind): IndexInfo | undefined;
20132014
getSignaturesOfType(type: Type, kind: SignatureKind): readonly Signature[];
20142015
getIndexTypeOfType(type: Type, kind: IndexKind): Type | undefined;
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
EmitSkipped: false
2+
FileName : ./dist/index.js
3+
"use strict";
4+
Object.defineProperty(exports, "__esModule", { value: true });
5+
var Foo = /** @class */ (function () {
6+
function Foo() {
7+
}
8+
Foo.prototype.methodName = function (propName) { };
9+
Foo.prototype.otherMethod = function () {
10+
if (Math.random() > 0.5) {
11+
return { x: 42 };
12+
}
13+
return { y: "yes" };
14+
};
15+
return Foo;
16+
}());
17+
exports.Foo = Foo;
18+
FileName : ./dist/index.d.ts.map
19+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../tests/cases/fourslash/index.ts"],"names":[],"mappings":"AAAA,qBAAa,GAAG;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;IACpC,WAAW;;;;;;;CAMd;AAED,MAAM,WAAW,QAAQ;IACrB,MAAM,EAAE,MAAM,CAAC;CAClB"}FileName : ./dist/index.d.ts
20+
export declare class Foo {
21+
member: string;
22+
methodName(propName: SomeType): void;
23+
otherMethod(): {
24+
x: number;
25+
y?: undefined;
26+
} | {
27+
y: string;
28+
x?: undefined;
29+
};
30+
}
31+
export interface SomeType {
32+
member: number;
33+
}
34+
//# sourceMappingURL=index.d.ts.map
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
EmitSkipped: false
2+
FileName : ./dist/index.js.map
3+
{"version":3,"file":"index.js","sourceRoot":"/tests/cases/fourslash/","sources":["index.ts"],"names":[],"mappings":";;AAAA;IAAA;IASA,CAAC;IAPG,wBAAU,GAAV,UAAW,QAAkB,IAAS,CAAC;IACvC,yBAAW,GAAX;QACI,IAAI,IAAI,CAAC,MAAM,EAAE,GAAG,GAAG,EAAE;YACrB,OAAO,EAAC,CAAC,EAAE,EAAE,EAAC,CAAC;SAClB;QACD,OAAO,EAAC,CAAC,EAAE,KAAK,EAAC,CAAC;IACtB,CAAC;IACL,UAAC;AAAD,CAAC,AATD,IASC;AATY,kBAAG"}FileName : ./dist/index.js
4+
"use strict";
5+
Object.defineProperty(exports, "__esModule", { value: true });
6+
var Foo = /** @class */ (function () {
7+
function Foo() {
8+
}
9+
Foo.prototype.methodName = function (propName) { };
10+
Foo.prototype.otherMethod = function () {
11+
if (Math.random() > 0.5) {
12+
return { x: 42 };
13+
}
14+
return { y: "yes" };
15+
};
16+
return Foo;
17+
}());
18+
exports.Foo = Foo;
19+
//# sourceMappingURL=index.js.mapFileName : ./dist/index.d.ts.map
20+
{"version":3,"file":"index.d.ts","sourceRoot":"/tests/cases/fourslash/","sources":["index.ts"],"names":[],"mappings":"AAAA,qBAAa,GAAG;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;IACpC,WAAW;;;;;;;CAMd;AAED,MAAM,WAAW,QAAQ;IACrB,MAAM,EAAE,MAAM,CAAC;CAClB"}FileName : ./dist/index.d.ts
21+
export declare class Foo {
22+
member: string;
23+
methodName(propName: SomeType): void;
24+
otherMethod(): {
25+
x: number;
26+
y?: undefined;
27+
} | {
28+
y: string;
29+
x?: undefined;
30+
};
31+
}
32+
export interface SomeType {
33+
member: number;
34+
}
35+
//# sourceMappingURL=index.d.ts.map
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
EmitSkipped: false
2+
FileName : ./dist/index.js
3+
"use strict";
4+
Object.defineProperty(exports, "__esModule", { value: true });
5+
var Foo = /** @class */ (function () {
6+
function Foo() {
7+
}
8+
Foo.prototype.methodName = function (propName) { };
9+
Foo.prototype.otherMethod = function () {
10+
if (Math.random() > 0.5) {
11+
return { x: 42 };
12+
}
13+
return { y: "yes" };
14+
};
15+
return Foo;
16+
}());
17+
exports.Foo = Foo;
18+
FileName : ./dist/index.d.ts.map
19+
{"version":3,"file":"index.d.ts","sourceRoot":"/tests/cases/fourslash/","sources":["index.ts"],"names":[],"mappings":"AAAA,qBAAa,GAAG;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;IACpC,WAAW;;;;;;;CAMd;AAED,MAAM,WAAW,QAAQ;IACrB,MAAM,EAAE,MAAM,CAAC;CAClB"}FileName : ./dist/index.d.ts
20+
export declare class Foo {
21+
member: string;
22+
methodName(propName: SomeType): void;
23+
otherMethod(): {
24+
x: number;
25+
y?: undefined;
26+
} | {
27+
y: string;
28+
x?: undefined;
29+
};
30+
}
31+
export interface SomeType {
32+
member: number;
33+
}
34+
//# sourceMappingURL=index.d.ts.map
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
EmitSkipped: false
2+
FileName : ./dist/index.js
3+
"use strict";
4+
Object.defineProperty(exports, "__esModule", { value: true });
5+
var Foo = /** @class */ (function () {
6+
function Foo() {
7+
}
8+
Foo.prototype.methodName = function (propName) { };
9+
Foo.prototype.otherMethod = function () {
10+
if (Math.random() > 0.5) {
11+
return { x: 42 };
12+
}
13+
return { y: "yes" };
14+
};
15+
return Foo;
16+
}());
17+
exports.Foo = Foo;
18+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90ZXN0cy9jYXNlcy9mb3Vyc2xhc2gvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQTtJQUFBO0lBU0EsQ0FBQztJQVBHLHdCQUFVLEdBQVYsVUFBVyxRQUFrQixJQUFTLENBQUM7SUFDdkMseUJBQVcsR0FBWDtRQUNJLElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRSxHQUFHLEdBQUcsRUFBRTtZQUNyQixPQUFPLEVBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBQyxDQUFDO1NBQ2xCO1FBQ0QsT0FBTyxFQUFDLENBQUMsRUFBRSxLQUFLLEVBQUMsQ0FBQztJQUN0QixDQUFDO0lBQ0wsVUFBQztBQUFELENBQUMsQUFURCxJQVNDO0FBVFksa0JBQUcifQ==FileName : ./dist/index.d.ts.map
19+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../tests/cases/fourslash/index.ts"],"names":[],"mappings":"AAAA,qBAAa,GAAG;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;IACpC,WAAW;;;;;;;CAMd;AAED,MAAM,WAAW,QAAQ;IACrB,MAAM,EAAE,MAAM,CAAC;CAClB"}FileName : ./dist/index.d.ts
20+
export declare class Foo {
21+
member: string;
22+
methodName(propName: SomeType): void;
23+
otherMethod(): {
24+
x: number;
25+
y?: undefined;
26+
} | {
27+
y: string;
28+
x?: undefined;
29+
};
30+
}
31+
export interface SomeType {
32+
member: number;
33+
}
34+
//# sourceMappingURL=index.d.ts.map
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
EmitSkipped: false
2+
FileName : ./dist/index.js
3+
"use strict";
4+
Object.defineProperty(exports, "__esModule", { value: true });
5+
var Foo = /** @class */ (function () {
6+
function Foo() {
7+
}
8+
Foo.prototype.methodName = function (propName) { };
9+
Foo.prototype.otherMethod = function () {
10+
if (Math.random() > 0.5) {
11+
return { x: 42 };
12+
}
13+
return { y: "yes" };
14+
};
15+
return Foo;
16+
}());
17+
exports.Foo = Foo;
18+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90ZXN0cy9jYXNlcy9mb3Vyc2xhc2gvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQTtJQUFBO0lBU0EsQ0FBQztJQVBHLHdCQUFVLEdBQVYsVUFBVyxRQUFrQixJQUFTLENBQUM7SUFDdkMseUJBQVcsR0FBWDtRQUNJLElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRSxHQUFHLEdBQUcsRUFBRTtZQUNyQixPQUFPLEVBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBQyxDQUFDO1NBQ2xCO1FBQ0QsT0FBTyxFQUFDLENBQUMsRUFBRSxLQUFLLEVBQUMsQ0FBQztJQUN0QixDQUFDO0lBQ0wsVUFBQztBQUFELENBQUMsQUFURCxJQVNDO0FBVFksa0JBQUciLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgY2xhc3MgRm9vIHtcbiAgICBtZW1iZXI6IHN0cmluZztcbiAgICBtZXRob2ROYW1lKHByb3BOYW1lOiBTb21lVHlwZSk6IHZvaWQge31cbiAgICBvdGhlck1ldGhvZCgpIHtcbiAgICAgICAgaWYgKE1hdGgucmFuZG9tKCkgPiAwLjUpIHtcbiAgICAgICAgICAgIHJldHVybiB7eDogNDJ9O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB7eTogXCJ5ZXNcIn07XG4gICAgfVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIFNvbWVUeXBlIHtcbiAgICBtZW1iZXI6IG51bWJlcjtcbn0iXX0=FileName : ./dist/index.d.ts.map
19+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../tests/cases/fourslash/index.ts"],"names":[],"mappings":"AAAA,qBAAa,GAAG;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;IACpC,WAAW;;;;;;;CAMd;AAED,MAAM,WAAW,QAAQ;IACrB,MAAM,EAAE,MAAM,CAAC;CAClB"}FileName : ./dist/index.d.ts
20+
export declare class Foo {
21+
member: string;
22+
methodName(propName: SomeType): void;
23+
otherMethod(): {
24+
x: number;
25+
y?: undefined;
26+
} | {
27+
y: string;
28+
x?: undefined;
29+
};
30+
}
31+
export interface SomeType {
32+
member: number;
33+
}
34+
//# sourceMappingURL=index.d.ts.map
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
tests/cases/conformance/classes/members/privateNames/privateNameAndIndexSignature.ts(6,14): error TS2339: Property '#f' does not exist on type 'A'.
2+
3+
4+
==== tests/cases/conformance/classes/members/privateNames/privateNameAndIndexSignature.ts (1 errors) ====
5+
// @target es6
6+
7+
class A {
8+
[k: string]: any;
9+
constructor(message: string) {
10+
this.#f = 3 // Error Property '#f' does not exist on type 'A'.
11+
~~
12+
!!! error TS2339: Property '#f' does not exist on type 'A'.
13+
}
14+
}
15+
Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
//// [privateNameAndIndexSignature.ts]
2+
// @target es6
3+
24
class A {
35
[k: string]: any;
46
constructor(message: string) {
@@ -7,10 +9,18 @@ class A {
79
}
810

911

10-
//// [privateNameAndIndexSignature.js]
11-
var A = /** @class */ (function () {
12-
function A(message) {
13-
this.#f = 3; // Error Property '#f' does not exist on type 'A'.
14-
}
15-
return A;
16-
}());
12+
tests/cases/conformance/classes/members/privateNames/privateNameAndIndexSignature.js(5,15): error TS1003: Identifier expected.
13+
14+
15+
==== tests/cases/conformance/classes/members/privateNames/privateNameAndIndexSignature.js (1 errors) ====
16+
"use strict";
17+
// @target es6
18+
var A = /** @class */ (function () {
19+
function A(message) {
20+
this. = 3; // Error Property '#f' does not exist on type 'A'.
21+
~
22+
!!! error TS1003: Identifier expected.
23+
}
24+
return A;
25+
}());
26+

0 commit comments

Comments
 (0)