Skip to content

Commit 6c755c9

Browse files
committed
Report property errors in the checker instead of the parser
1 parent 068d10c commit 6c755c9

13 files changed

+100
-47
lines changed

src/compiler/checker.ts

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -532,7 +532,7 @@ namespace ts {
532532
}
533533

534534
// Because of module/namespace merging, a module's exports are in scope,
535-
// yet we never want to treat an export specifier as putting a member in scope.
535+
// yet we never want to treat an export specifier as putting a member in scope.
536536
// Therefore, if the name we find is purely an export specifier, it is not actually considered in scope.
537537
// Two things to note about this:
538538
// 1. We have to check this without calling getSymbol. The problem with calling getSymbol
@@ -11398,7 +11398,7 @@ namespace ts {
1139811398
// we can get here in two cases
1139911399
// 1. mixed static and instance class members
1140011400
// 2. something with the same name was defined before the set of overloads that prevents them from merging
11401-
// here we'll report error only for the first case since for second we should already report error in binder
11401+
// here we'll report error only for the first case since for second we should already report error in binder
1140211402
if (reportError) {
1140311403
const diagnostic = node.flags & NodeFlags.Static ? Diagnostics.Function_overload_must_be_static : Diagnostics.Function_overload_must_not_be_static;
1140411404
error(errorNode, diagnostic);
@@ -12065,8 +12065,8 @@ namespace ts {
1206512065
const symbol = getSymbolOfNode(node);
1206612066
const localSymbol = node.localSymbol || symbol;
1206712067

12068-
// Since the javascript won't do semantic analysis like typescript,
12069-
// if the javascript file comes before the typescript file and both contain same name functions,
12068+
// Since the javascript won't do semantic analysis like typescript,
12069+
// if the javascript file comes before the typescript file and both contain same name functions,
1207012070
// checkFunctionOrConstructorSymbol wouldn't be called if we didnt ignore javascript function.
1207112071
const firstDeclaration = forEach(localSymbol.declarations,
1207212072
// Get first non javascript function declaration
@@ -15735,6 +15735,16 @@ namespace ts {
1573515735
}
1573615736
}
1573715737

15738+
// Report an error if an interface property has an initializer
15739+
if (node.members) {
15740+
const members = <NodeArray<PropertySignature>>node.members;
15741+
for (const element of members) {
15742+
if (element.initializer) {
15743+
return grammarErrorOnFirstToken(element.initializer, Diagnostics.An_interface_property_cannot_have_an_initializer);
15744+
}
15745+
}
15746+
}
15747+
1573815748
return false;
1573915749
}
1574015750

@@ -16085,6 +16095,18 @@ namespace ts {
1608516095
}
1608616096
}
1608716097

16098+
if (node.type) {
16099+
const typeLiteralNode = <TypeLiteralNode>node.type;
16100+
if (typeLiteralNode.members) {
16101+
for (const element of typeLiteralNode.members) {
16102+
const propertySignature = <PropertySignature>element;
16103+
if (propertySignature.initializer) {
16104+
return grammarErrorOnNode(propertySignature.initializer, Diagnostics.An_object_type_literal_property_cannot_have_an_initializer);
16105+
}
16106+
}
16107+
}
16108+
}
16109+
1608816110
const checkLetConstNames = languageVersion >= ScriptTarget.ES6 && (isLet(node) || isConst(node));
1608916111

1609016112
// 1. LexicalDeclaration : LetOrConst BindingList ;

src/compiler/diagnosticMessages.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -783,10 +783,14 @@
783783
"category": "Error",
784784
"code": 1245
785785
},
786-
"An object type property cannot have an initializer.": {
786+
"An interface property cannot have an initializer.": {
787787
"category": "Error",
788788
"code": 1246
789789
},
790+
"An object type literal property cannot have an initializer.": {
791+
"category": "Error",
792+
"code": 1247
793+
},
790794

791795
"'with' statements are not allowed in an async function block.": {
792796
"category": "Error",

src/compiler/parser.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2249,10 +2249,9 @@ namespace ts {
22492249
property.type = parseTypeAnnotation();
22502250

22512251
// Although object type properties cannot not have initializers, we attempt to parse an initializer
2252-
// so we can report that an object type property cannot have an initializer.
2253-
if (token === SyntaxKind.EqualsToken && lookAhead(() => parseNonParameterInitializer()) !== undefined) {
2254-
parseErrorAtCurrentToken(Diagnostics.An_object_type_property_cannot_have_an_initializer);
2255-
}
2252+
// so we can report in the checker that an interface property or object type literal property cannot
2253+
// have an initializer.
2254+
property.initializer = parseNonParameterInitializer();
22562255

22572256
parseTypeMemberSemicolon();
22582257
return finishNode(property);

src/compiler/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -586,6 +586,7 @@ namespace ts {
586586
name: PropertyName; // Declared property name
587587
questionToken?: Node; // Present on optional property
588588
type?: TypeNode; // Optional type annotation
589+
initializer?: Expression; // Optional initializer
589590
}
590591

591592
// @kind(SyntaxKind.PropertyDeclaration)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
tests/cases/compiler/errorOnInitializerInInterfaceProperty.ts(2,19): error TS1246: An interface property cannot have an initializer.
2+
3+
4+
==== tests/cases/compiler/errorOnInitializerInInterfaceProperty.ts (1 errors) ====
5+
interface Foo {
6+
bar: number = 5;
7+
~
8+
!!! error TS1246: An interface property cannot have an initializer.
9+
}
10+
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
//// [errorOnInitializerInInterfaceProperty.ts]
2+
interface Foo {
3+
bar: number = 5;
4+
}
5+
6+
7+
//// [errorOnInitializerInInterfaceProperty.js]

tests/baselines/reference/errorOnInitializerInObjectType.errors.txt

Lines changed: 0 additions & 17 deletions
This file was deleted.

tests/baselines/reference/errorOnInitializerInObjectType.js

Lines changed: 0 additions & 12 deletions
This file was deleted.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
tests/cases/compiler/errorOnInitializerInObjectTypeLiteralProperty.ts(2,19): error TS1247: An object type literal property cannot have an initializer.
2+
tests/cases/compiler/errorOnInitializerInObjectTypeLiteralProperty.ts(6,19): error TS1247: An object type literal property cannot have an initializer.
3+
4+
5+
==== tests/cases/compiler/errorOnInitializerInObjectTypeLiteralProperty.ts (2 errors) ====
6+
var Foo: {
7+
bar: number = 5;
8+
~
9+
!!! error TS1247: An object type literal property cannot have an initializer.
10+
};
11+
12+
let Bar: {
13+
bar: number = 5;
14+
~
15+
!!! error TS1247: An object type literal property cannot have an initializer.
16+
};
17+
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//// [errorOnInitializerInObjectTypeLiteralProperty.ts]
2+
var Foo: {
3+
bar: number = 5;
4+
};
5+
6+
let Bar: {
7+
bar: number = 5;
8+
};
9+
10+
11+
//// [errorOnInitializerInObjectTypeLiteralProperty.js]
12+
var Foo;
13+
var Bar;

tests/baselines/reference/objectTypeLiteralSyntax2.errors.txt

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
tests/cases/conformance/types/objectTypeLiteral/objectTypeLiteralSyntax2.ts(12,22): error TS1005: ';' expected.
1+
tests/cases/conformance/types/objectTypeLiteral/objectTypeLiteralSyntax2.ts(12,22): error TS1005: '=' expected.
2+
tests/cases/conformance/types/objectTypeLiteral/objectTypeLiteralSyntax2.ts(12,22): error TS2304: Cannot find name 'bar'.
3+
tests/cases/conformance/types/objectTypeLiteral/objectTypeLiteralSyntax2.ts(12,25): error TS1005: ';' expected.
24

35

4-
==== tests/cases/conformance/types/objectTypeLiteral/objectTypeLiteralSyntax2.ts (1 errors) ====
6+
==== tests/cases/conformance/types/objectTypeLiteral/objectTypeLiteralSyntax2.ts (3 errors) ====
57
var x: {
68
foo: string,
79
bar: string
@@ -15,4 +17,8 @@ tests/cases/conformance/types/objectTypeLiteral/objectTypeLiteralSyntax2.ts(12,2
1517

1618
var z: { foo: string bar: string }
1719
~~~
20+
!!! error TS1005: '=' expected.
21+
~~~
22+
!!! error TS2304: Cannot find name 'bar'.
23+
~
1824
!!! error TS1005: ';' expected.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
interface Foo {
2+
bar: number = 5;
3+
}
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
interface Foo {
2-
bar: number = 5;
3-
}
4-
5-
var Foo: {
6-
bar: number = 5;
7-
};
1+
var Foo: {
2+
bar: number = 5;
3+
};
4+
5+
let Bar: {
6+
bar: number = 5;
7+
};

0 commit comments

Comments
 (0)