Definite assignment assertion '!' on variable and property declarations
This commit is contained in:
parent
87a8d41e11
commit
1624e1bc1a
4 changed files with 32 additions and 5 deletions
|
@ -13121,8 +13121,10 @@ namespace ts {
|
|||
// the entire control flow graph from the variable's declaration (i.e. when the flow container and
|
||||
// declaration container are the same).
|
||||
const assumeInitialized = isParameter || isAlias || isOuterVariable ||
|
||||
type !== autoType && type !== autoArrayType && (!strictNullChecks || (type.flags & TypeFlags.Any) !== 0 || isInTypeQuery(node) || node.parent.kind === SyntaxKind.ExportSpecifier) ||
|
||||
type !== autoType && type !== autoArrayType && (!strictNullChecks || (type.flags & TypeFlags.Any) !== 0 ||
|
||||
isInTypeQuery(node) || node.parent.kind === SyntaxKind.ExportSpecifier) ||
|
||||
node.parent.kind === SyntaxKind.NonNullExpression ||
|
||||
declaration.kind === SyntaxKind.VariableDeclaration && (<VariableDeclaration>declaration).exclamationToken ||
|
||||
declaration.flags & NodeFlags.Ambient;
|
||||
const initialType = assumeInitialized ? (isParameter ? removeOptionalityFromDeclaredType(type, getRootDeclaration(declaration) as VariableLikeDeclaration) : type) :
|
||||
type === autoType || type === autoArrayType ? undefinedType :
|
||||
|
@ -22669,6 +22671,7 @@ namespace ts {
|
|||
function isInstancePropertyWithoutInitializer(node: Node) {
|
||||
return node.kind === SyntaxKind.PropertyDeclaration &&
|
||||
!hasModifier(node, ModifierFlags.Static | ModifierFlags.Abstract) &&
|
||||
!(<PropertyDeclaration>node).exclamationToken &&
|
||||
!(<PropertyDeclaration>node).initializer;
|
||||
}
|
||||
|
||||
|
@ -26101,6 +26104,10 @@ namespace ts {
|
|||
}
|
||||
}
|
||||
|
||||
if (node.exclamationToken && (node.parent.parent.kind !== SyntaxKind.VariableStatement || !node.type || node.initializer || node.flags & NodeFlags.Ambient)) {
|
||||
return grammarErrorOnNode(node.exclamationToken, Diagnostics.A_definite_assignment_assertion_is_not_permitted_in_this_context);
|
||||
}
|
||||
|
||||
if (compilerOptions.module !== ModuleKind.ES2015 && compilerOptions.module !== ModuleKind.ESNext && compilerOptions.module !== ModuleKind.System && !compilerOptions.noEmit &&
|
||||
!(node.parent.parent.flags & NodeFlags.Ambient) && hasModifier(node.parent.parent, ModifierFlags.Export)) {
|
||||
checkESModuleMarker(node.name);
|
||||
|
@ -26264,6 +26271,11 @@ namespace ts {
|
|||
if (node.flags & NodeFlags.Ambient && node.initializer) {
|
||||
return grammarErrorOnFirstToken(node.initializer, Diagnostics.Initializers_are_not_allowed_in_ambient_contexts);
|
||||
}
|
||||
|
||||
if (node.exclamationToken && (!isClassLike(node.parent) || !node.type || node.initializer ||
|
||||
node.flags & NodeFlags.Ambient || hasModifier(node, ModifierFlags.Static | ModifierFlags.Abstract))) {
|
||||
return grammarErrorOnNode(node.exclamationToken, Diagnostics.A_definite_assignment_assertion_is_not_permitted_in_this_context);
|
||||
}
|
||||
}
|
||||
|
||||
function checkGrammarTopLevelElementForRequiredDeclareModifier(node: Node): boolean {
|
||||
|
|
|
@ -831,6 +831,10 @@
|
|||
"category": "Error",
|
||||
"code": 1254
|
||||
},
|
||||
"A definite assignment assertion '!' is not permitted in this context.": {
|
||||
"category": "Error",
|
||||
"code": 1255
|
||||
},
|
||||
"'with' statements are not allowed in an async function block.": {
|
||||
"category": "Error",
|
||||
"code": 1300
|
||||
|
|
|
@ -99,6 +99,7 @@ namespace ts {
|
|||
visitNode(cbNode, (<VariableLikeDeclaration>node).dotDotDotToken) ||
|
||||
visitNode(cbNode, (<VariableLikeDeclaration>node).name) ||
|
||||
visitNode(cbNode, (<VariableLikeDeclaration>node).questionToken) ||
|
||||
visitNode(cbNode, (<VariableLikeDeclaration>node).exclamationToken) ||
|
||||
visitNode(cbNode, (<VariableLikeDeclaration>node).type) ||
|
||||
visitNode(cbNode, (<VariableLikeDeclaration>node).initializer);
|
||||
case SyntaxKind.FunctionType:
|
||||
|
@ -5254,6 +5255,9 @@ namespace ts {
|
|||
function parseVariableDeclaration(): VariableDeclaration {
|
||||
const node = <VariableDeclaration>createNode(SyntaxKind.VariableDeclaration);
|
||||
node.name = parseIdentifierOrPattern();
|
||||
if (node.name.kind === SyntaxKind.Identifier && token() === SyntaxKind.ExclamationToken && !scanner.hasPrecedingLineBreak()) {
|
||||
node.exclamationToken = parseTokenNode();
|
||||
}
|
||||
node.type = parseTypeAnnotation();
|
||||
if (!isInOrOfKeyword(token())) {
|
||||
node.initializer = parseInitializer();
|
||||
|
@ -5346,6 +5350,9 @@ namespace ts {
|
|||
|
||||
function parsePropertyDeclaration(node: PropertyDeclaration): PropertyDeclaration {
|
||||
node.kind = SyntaxKind.PropertyDeclaration;
|
||||
if (!node.questionToken && token() === SyntaxKind.ExclamationToken && !scanner.hasPrecedingLineBreak()) {
|
||||
node.exclamationToken = parseTokenNode();
|
||||
}
|
||||
node.type = parseTypeAnnotation();
|
||||
|
||||
// For instance properties specifically, since they are evaluated inside the constructor,
|
||||
|
|
|
@ -598,6 +598,7 @@ namespace ts {
|
|||
|
||||
export type DotDotDotToken = Token<SyntaxKind.DotDotDotToken>;
|
||||
export type QuestionToken = Token<SyntaxKind.QuestionToken>;
|
||||
export type ExclamationToken = Token<SyntaxKind.ExclamationToken>;
|
||||
export type ColonToken = Token<SyntaxKind.ColonToken>;
|
||||
export type EqualsToken = Token<SyntaxKind.EqualsToken>;
|
||||
export type AsteriskToken = Token<SyntaxKind.AsteriskToken>;
|
||||
|
@ -762,6 +763,7 @@ namespace ts {
|
|||
kind: SyntaxKind.VariableDeclaration;
|
||||
parent?: VariableDeclarationList | CatchClause;
|
||||
name: BindingName; // Declared variable name
|
||||
exclamationToken?: ExclamationToken; // Optional definite assignment assertion
|
||||
type?: TypeNode; // Optional type annotation
|
||||
initializer?: Expression; // Optional initializer
|
||||
}
|
||||
|
@ -801,8 +803,9 @@ namespace ts {
|
|||
|
||||
export interface PropertyDeclaration extends ClassElement, JSDocContainer {
|
||||
kind: SyntaxKind.PropertyDeclaration;
|
||||
questionToken?: QuestionToken; // Present for use with reporting a grammar error
|
||||
name: PropertyName;
|
||||
questionToken?: QuestionToken; // Present for use with reporting a grammar error
|
||||
exclamationToken?: ExclamationToken;
|
||||
type?: TypeNode;
|
||||
initializer?: Expression; // Optional initializer
|
||||
}
|
||||
|
@ -860,6 +863,7 @@ namespace ts {
|
|||
dotDotDotToken?: DotDotDotToken;
|
||||
name: DeclarationName;
|
||||
questionToken?: QuestionToken;
|
||||
exclamationToken?: ExclamationToken;
|
||||
type?: TypeNode;
|
||||
initializer?: Expression;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue