β¬ οΈ Back to Table of Contents
π no-non-null-asserted-nullish-coalescing¶
π Analysis Summary¶
| Metric | Count |
|---|---|
| π§ Functions | 3 |
| π¦ Imports | 8 |
π Table of Contents¶
π οΈ File Location:¶
π packages/eslint-plugin/src/rules/no-non-null-asserted-nullish-coalescing.ts
π€ Default Export¶
| Property | Value |
|---|---|
name |
'no-non-null-asserted-nullish-coalescing' |
meta.type |
'problem' |
meta.docs.description |
'Disallow non-null assertions in the left operand of a nullish coalescing operator' |
meta.docs.recommended |
'strict' |
meta.hasSuggestions |
true |
meta.messages.noNonNullAssertedNullishCoalescing |
'The nullish coalescing operator is designed to handle undefined and null - using a non-null assertion is not needed.' |
meta.messages.suggestRemovingNonNull |
'Remove the non-null assertion.' |
meta.schema |
[] |
defaultOptions |
[] |
Entry point: create β documented under Functions.
π¦ Imports¶
| Name | Source |
|---|---|
Definition |
@typescript-eslint/scope-manager |
TSESLint |
@typescript-eslint/utils |
DefinitionType |
@typescript-eslint/scope-manager |
ASTUtils |
@typescript-eslint/utils |
TSESTree |
@typescript-eslint/utils |
createRule |
../util |
nullThrows |
../util |
NullThrowsReasons |
../util |
Functions¶
create(context: any): { 'LogicalExpression[operator = "??"] > TSNonNullExpression⦶
Parameters:
contextany
Returns: { 'LogicalExpression[operator = "??"] > TSNonNullExpression.left'(node: TSESTree.TSNonNullExpression): void; }
Calls:
context.sourceCode.getScopeASTUtils.findVariablehasAssignmentBeforeNodecontext.reportnullThrows (from ../util)context.sourceCode.getLastTokenNullThrowsReasons.MissingTokenfixer.remove
Internal Comments:
/*
Use a suggestion instead of a fixer, because this can break type checks.
The resulting type of the nullish coalesce is only influenced by the right operand if the left operand can be `null` or `undefined`.
After removing the non-null assertion the type of the left operand might contain `null` or `undefined` and then the type of the right operand
might change the resulting type of the nullish coalesce.
See the following example:
function test(x?: string): string {
const bar = x! ?? false; // type analysis reports `bar` has type `string`
// x ?? false; // type analysis reports `bar` has type `string | false`
return bar;
}
*/ (x2)
Code
create(context) {
return {
'LogicalExpression[operator = "??"] > TSNonNullExpression.left'(
node: TSESTree.TSNonNullExpression,
): void {
if (node.expression.type === TSESTree.AST_NODE_TYPES.Identifier) {
const scope = context.sourceCode.getScope(node);
const identifier = node.expression;
const variable = ASTUtils.findVariable(scope, identifier.name);
if (variable && !hasAssignmentBeforeNode(variable, node)) {
return;
}
}
context.report({
node,
messageId: 'noNonNullAssertedNullishCoalescing',
/*
Use a suggestion instead of a fixer, because this can break type checks.
The resulting type of the nullish coalesce is only influenced by the right operand if the left operand can be `null` or `undefined`.
After removing the non-null assertion the type of the left operand might contain `null` or `undefined` and then the type of the right operand
might change the resulting type of the nullish coalesce.
See the following example:
function test(x?: string): string {
const bar = x! ?? false; // type analysis reports `bar` has type `string`
// x ?? false; // type analysis reports `bar` has type `string | false`
return bar;
}
*/
suggest: [
{
messageId: 'suggestRemovingNonNull',
fix(fixer): TSESLint.RuleFix {
const exclamationMark = nullThrows(
context.sourceCode.getLastToken(
node,
ASTUtils.isNonNullAssertionPunctuator,
),
NullThrowsReasons.MissingToken('!', 'Non-null Assertion'),
);
return fixer.remove(exclamationMark);
},
},
],
});
},
};
}
hasAssignmentBeforeNode(variable: TSESLint.Scope.Variable, node: TSESTree.Node): boolean¶
Parameters:
variableTSESLint.Scope.VariablenodeTSESTree.Node
Returns: boolean
Calls:
variable.references.someref.isWritevariable.defs.someisDefinitionWithAssignment
Code
function hasAssignmentBeforeNode(
variable: TSESLint.Scope.Variable,
node: TSESTree.Node,
): boolean {
return (
variable.references.some(
ref => ref.isWrite() && ref.identifier.range[1] < node.range[1],
) ||
variable.defs.some(
def =>
isDefinitionWithAssignment(def) && def.node.range[1] < node.range[1],
)
);
}
isDefinitionWithAssignment(definition: Definition): boolean¶
Parameters:
definitionDefinition
Returns: boolean
Code
Generated by Syntax Scribe