mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Add strict property initialization checks
This commit is contained in:
+29
-1
@@ -11925,7 +11925,7 @@ namespace ts {
|
||||
// on empty arrays are possible without implicit any errors and new element types can be inferred without
|
||||
// type mismatch errors.
|
||||
const resultType = getObjectFlags(evolvedType) & ObjectFlags.EvolvingArray && isEvolvingArrayOperationTarget(reference) ? anyArrayType : finalizeEvolvingArrayType(evolvedType);
|
||||
if (reference.parent.kind === SyntaxKind.NonNullExpression && getTypeWithFacts(resultType, TypeFacts.NEUndefinedOrNull).flags & TypeFlags.Never) {
|
||||
if (reference.parent && reference.parent.kind === SyntaxKind.NonNullExpression && getTypeWithFacts(resultType, TypeFacts.NEUndefinedOrNull).flags & TypeFlags.Never) {
|
||||
return declaredType;
|
||||
}
|
||||
return resultType;
|
||||
@@ -22072,6 +22072,7 @@ namespace ts {
|
||||
if (produceDiagnostics) {
|
||||
checkIndexConstraints(type);
|
||||
checkTypeForDuplicateIndexSignatures(node);
|
||||
checkPropertyInitialization(node);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22228,6 +22229,33 @@ namespace ts {
|
||||
return ok;
|
||||
}
|
||||
|
||||
function checkPropertyInitialization(node: ClassLikeDeclaration) {
|
||||
if (!strictNullChecks || node.flags & NodeFlags.Ambient) {
|
||||
return;
|
||||
}
|
||||
const constructor = findConstructorDeclaration(node);
|
||||
for (const member of node.members) {
|
||||
if (member.kind === SyntaxKind.PropertyDeclaration && !(<PropertyDeclaration>member).initializer) {
|
||||
const propName = (<PropertyDeclaration>member).name;
|
||||
if (isIdentifier(propName)) {
|
||||
const type = getTypeOfSymbol(getSymbolOfNode(member));
|
||||
if (!(type.flags & TypeFlags.Any || getFalsyFlags(type) & TypeFlags.Undefined)) {
|
||||
if (!constructor || !isPropertyInitializedInConstructor(propName, type, constructor)) {
|
||||
error(member.name, Diagnostics.Property_0_has_no_initializer_and_is_not_definitely_assigned_in_the_constructor, declarationNameToString(propName));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function isPropertyInitializedInConstructor(propName: Identifier, propType: Type, constructor: ConstructorDeclaration) {
|
||||
const reference = createPropertyAccess(createThis(), propName);
|
||||
reference.flowNode = constructor.returnFlowNode;
|
||||
const flowType = getFlowTypeOfReference(reference, propType, getOptionalType(propType));
|
||||
return !(getFalsyFlags(flowType) & TypeFlags.Undefined);
|
||||
}
|
||||
|
||||
function checkInterfaceDeclaration(node: InterfaceDeclaration) {
|
||||
// Grammar checking
|
||||
if (!checkGrammarDecoratorsAndModifiers(node)) checkGrammarInterfaceDeclaration(node);
|
||||
|
||||
@@ -1928,6 +1928,10 @@
|
||||
"category": "Error",
|
||||
"code": 2563
|
||||
},
|
||||
"Property '{0}' has no initializer and is not definitely assigned in the constructor.": {
|
||||
"category": "Error",
|
||||
"code": 2564
|
||||
},
|
||||
"JSX element attributes type '{0}' may not be a union type.": {
|
||||
"category": "Error",
|
||||
"code": 2600
|
||||
|
||||
Reference in New Issue
Block a user