diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 71c19e1214a..0f057e61667 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3216,7 +3216,9 @@ namespace ts { function getTypeOfFuncClassEnumModule(symbol: Symbol): Type { const links = getSymbolLinks(symbol); if (!links.type) { - links.type = createObjectType(TypeFlags.Anonymous, symbol); + const type = createObjectType(TypeFlags.Anonymous, symbol); + links.type = strictNullChecks && symbol.flags & SymbolFlags.Optional ? + addNullableKind(type, TypeFlags.Undefined) : type; } return links.type; } @@ -9921,7 +9923,8 @@ namespace ts { } const propType = getTypeOfSymbol(prop); - if (node.kind !== SyntaxKind.PropertyAccessExpression || !(prop.flags & (SymbolFlags.Variable | SymbolFlags.Property | SymbolFlags.Accessor)) || isAssignmentTarget(node)) { + if (node.kind !== SyntaxKind.PropertyAccessExpression || isAssignmentTarget(node) || + !(propType.flags & TypeFlags.Union) && !(prop.flags & (SymbolFlags.Variable | SymbolFlags.Property | SymbolFlags.Accessor))) { return propType; } const leftmostNode = getLeftmostIdentifierOrThis(node); @@ -13396,7 +13399,7 @@ namespace ts { // Abstract methods can't have an implementation -- in particular, they don't need one. if (!isExportSymbolInsideModule && lastSeenNonAmbientDeclaration && !lastSeenNonAmbientDeclaration.body && - !(lastSeenNonAmbientDeclaration.flags & NodeFlags.Abstract)) { + !(lastSeenNonAmbientDeclaration.flags & NodeFlags.Abstract) && !lastSeenNonAmbientDeclaration.questionToken) { reportImplementationExpectedError(lastSeenNonAmbientDeclaration); } @@ -18290,7 +18293,7 @@ namespace ts { } if (node.parent.kind === SyntaxKind.ObjectLiteralExpression) { - if (checkGrammarForInvalidQuestionMark(node, node.questionToken, Diagnostics.A_class_member_cannot_be_declared_optional)) { + if (checkGrammarForInvalidQuestionMark(node, node.questionToken, Diagnostics.An_object_member_cannot_be_declared_optional)) { return true; } else if (node.body === undefined) { @@ -18299,9 +18302,6 @@ namespace ts { } if (isClassLike(node.parent)) { - if (checkGrammarForInvalidQuestionMark(node, node.questionToken, Diagnostics.A_class_member_cannot_be_declared_optional)) { - return true; - } // Technically, computed properties in ambient contexts is disallowed // for property declarations and accessors too, not just methods. // However, property declarations disallow computed names in general, @@ -18523,8 +18523,7 @@ namespace ts { function checkGrammarProperty(node: PropertyDeclaration) { if (isClassLike(node.parent)) { - if (checkGrammarForInvalidQuestionMark(node, node.questionToken, Diagnostics.A_class_member_cannot_be_declared_optional) || - checkGrammarForNonSymbolComputedProperty(node.name, Diagnostics.A_computed_property_name_in_a_class_property_declaration_must_directly_refer_to_a_built_in_symbol)) { + if (checkGrammarForNonSymbolComputedProperty(node.name, Diagnostics.A_computed_property_name_in_a_class_property_declaration_must_directly_refer_to_a_built_in_symbol)) { return true; } } diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 899b4292f04..cb347234ec7 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -315,10 +315,6 @@ "category": "Error", "code": 1110 }, - "A class member cannot be declared optional.": { - "category": "Error", - "code": 1112 - }, "A 'default' clause cannot appear more than once in a 'switch' statement.": { "category": "Error", "code": 1113