Skip to content

Commit 31d6831

Browse files
committed
error message for private names in obj literals
1 parent 351c75c commit 31d6831

18 files changed

+181
-3
lines changed

src/compiler/binder.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,12 @@ namespace ts {
273273
}
274274
if (isPrivateName(name)) {
275275
// containingClass exists because private names only allowed inside classes
276-
const containingClassSymbol = getContainingClass(name.parent)!.symbol;
276+
const containingClass = getContainingClass(name.parent);
277+
if (!containingClass) {
278+
// we're in a case where there's a private name outside a class (invalid)
279+
return undefined;
280+
}
281+
const containingClassSymbol = containingClass.symbol;
277282
return getPropertyNameForPrivateNameDescription(containingClassSymbol, name.escapedText);
278283
}
279284
return isPropertyNameLiteral(name) ? getEscapedTextOfIdentifierOrLiteral(name) : undefined;

src/compiler/checker.ts

+4
Original file line numberDiff line numberDiff line change
@@ -29681,6 +29681,10 @@ namespace ts {
2968129681
return grammarErrorOnNode(prop.equalsToken!, Diagnostics.can_only_be_used_in_an_object_literal_property_inside_a_destructuring_assignment);
2968229682
}
2968329683

29684+
if (name.kind === SyntaxKind.PrivateName) {
29685+
return grammarErrorOnNode(name, Diagnostics.Private_names_are_not_allowed_outside_class_bodies);
29686+
}
29687+
2968429688
// Modifiers are never allowed on properties except for 'async' on a method declaration
2968529689
if (prop.modifiers) {
2968629690
for (const mod of prop.modifiers!) { // TODO: GH#19955

src/compiler/diagnosticMessages.json

+5-1
Original file line numberDiff line numberDiff line change
@@ -4319,10 +4319,14 @@
43194319
"category": "Error",
43204320
"code": 18008
43214321
},
4322-
"Property '{0}' is missing in type '{1}'. While type '{1}' has a private member with the same spelling, its declaration and accessibility are distinct": {
4322+
"Property '{0}' is missing in type '{1}'. While type '{1}' has a private member with the same spelling, its declaration and accessibility are distinct.": {
43234323
"category": "Error",
43244324
"code": 18009
43254325
},
4326+
"Private names are not allowed outside class bodies.": {
4327+
"category": "Error",
4328+
"code": 18010
4329+
},
43264330

43274331
"File is a CommonJS module; it may be converted to an ES6 module.": {
43284332
"category": "Suggestion",

src/compiler/types.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -822,7 +822,7 @@ namespace ts {
822822
expression: Expression;
823823
}
824824

825-
export interface PrivateName extends Declaration {
825+
export interface PrivateName extends Expression, Declaration {
826826
kind: SyntaxKind.PrivateName;
827827
// escaping not strictly necessary
828828
// avoids gotchas in transforms and utils
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
tests/cases/conformance/classes/members/privateNames/privateNameInObjectLiteral-1.ts(2,5): error TS18010: Private names are not allowed outside class bodies.
2+
3+
4+
==== tests/cases/conformance/classes/members/privateNames/privateNameInObjectLiteral-1.ts (1 errors) ====
5+
const obj = {
6+
#foo: 1
7+
~~~~
8+
!!! error TS18010: Private names are not allowed outside class bodies.
9+
};
10+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
//// [privateNameInObjectLiteral-1.ts]
2+
const obj = {
3+
#foo: 1
4+
};
5+
6+
7+
//// [privateNameInObjectLiteral-1.js]
8+
var obj = {
9+
#foo: 1
10+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
=== tests/cases/conformance/classes/members/privateNames/privateNameInObjectLiteral-1.ts ===
2+
const obj = {
3+
>obj : Symbol(obj, Decl(privateNameInObjectLiteral-1.ts, 0, 5))
4+
5+
#foo: 1
6+
>#foo : Symbol(#foo, Decl(privateNameInObjectLiteral-1.ts, 0, 13))
7+
8+
};
9+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
=== tests/cases/conformance/classes/members/privateNames/privateNameInObjectLiteral-1.ts ===
2+
const obj = {
3+
>obj : {}
4+
>{ #foo: 1} : {}
5+
6+
#foo: 1
7+
>#foo : number
8+
>1 : 1
9+
10+
};
11+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
tests/cases/conformance/classes/members/privateNames/privateNameInObjectLiteral-2.ts(2,5): error TS18010: Private names are not allowed outside class bodies.
2+
3+
4+
==== tests/cases/conformance/classes/members/privateNames/privateNameInObjectLiteral-2.ts (1 errors) ====
5+
const obj = {
6+
#foo() {
7+
~~~~
8+
!!! error TS18010: Private names are not allowed outside class bodies.
9+
10+
}
11+
};
12+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//// [privateNameInObjectLiteral-2.ts]
2+
const obj = {
3+
#foo() {
4+
5+
}
6+
};
7+
8+
9+
//// [privateNameInObjectLiteral-2.js]
10+
var obj = {
11+
#foo: function () {
12+
}
13+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
=== tests/cases/conformance/classes/members/privateNames/privateNameInObjectLiteral-2.ts ===
2+
const obj = {
3+
>obj : Symbol(obj, Decl(privateNameInObjectLiteral-2.ts, 0, 5))
4+
5+
#foo() {
6+
>#foo : Symbol(#foo, Decl(privateNameInObjectLiteral-2.ts, 0, 13))
7+
8+
}
9+
};
10+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
=== tests/cases/conformance/classes/members/privateNames/privateNameInObjectLiteral-2.ts ===
2+
const obj = {
3+
>obj : {}
4+
>{ #foo() { }} : {}
5+
6+
#foo() {
7+
>#foo : () => void
8+
9+
}
10+
};
11+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
tests/cases/conformance/classes/members/privateNames/privateNameInObjectLiteral.ts(2,5): error TS18010: Private names are not allowed outside class bodies.
2+
3+
4+
==== tests/cases/conformance/classes/members/privateNames/privateNameInObjectLiteral.ts (1 errors) ====
5+
const obj = {
6+
#foo: "#foo",
7+
~~~~
8+
!!! error TS18010: Private names are not allowed outside class bodies.
9+
#bar: () => true,
10+
#baz() {
11+
return true;
12+
}
13+
};
14+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//// [privateNameInObjectLiteral.ts]
2+
const obj = {
3+
#foo: "#foo",
4+
#bar: () => true,
5+
#baz() {
6+
return true;
7+
}
8+
};
9+
10+
11+
//// [privateNameInObjectLiteral.js]
12+
var obj = {
13+
#foo: "#foo",
14+
#bar: function () { return true; },
15+
#baz: function () {
16+
return true;
17+
}
18+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
=== tests/cases/conformance/classes/members/privateNames/privateNameInObjectLiteral.ts ===
2+
const obj = {
3+
>obj : Symbol(obj, Decl(privateNameInObjectLiteral.ts, 0, 5))
4+
5+
#foo: "#foo",
6+
>#foo : Symbol(#foo, Decl(privateNameInObjectLiteral.ts, 0, 13))
7+
8+
#bar: () => true,
9+
>#bar : Symbol(#bar, Decl(privateNameInObjectLiteral.ts, 1, 17))
10+
11+
#baz() {
12+
>#baz : Symbol(#baz, Decl(privateNameInObjectLiteral.ts, 2, 21))
13+
14+
return true;
15+
}
16+
};
17+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
=== tests/cases/conformance/classes/members/privateNames/privateNameInObjectLiteral.ts ===
2+
const obj = {
3+
>obj : {}
4+
>{ #foo: "#foo", #bar: () => true, #baz() { return true; }} : {}
5+
6+
#foo: "#foo",
7+
>#foo : string
8+
>"#foo" : "#foo"
9+
10+
#bar: () => true,
11+
>#bar : () => boolean
12+
>() => true : () => boolean
13+
>true : true
14+
15+
#baz() {
16+
>#baz : () => boolean
17+
18+
return true;
19+
>true : true
20+
}
21+
};
22+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
const obj = {
2+
#foo: 1
3+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
const obj = {
2+
#foo() {
3+
4+
}
5+
};

0 commit comments

Comments
 (0)