Skip to content

chore: enable no-non-null-assertion internally, excluding tests #8019

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,6 @@ export default tseslint.config(
{ allowIIFEs: true },
],
'@typescript-eslint/no-explicit-any': 'error',
'@typescript-eslint/no-non-null-assertion': 'off',
'no-constant-condition': 'off',
'@typescript-eslint/no-unnecessary-condition': [
'error',
Expand Down Expand Up @@ -343,6 +342,7 @@ export default tseslint.config(
'error',
{ allow: ['arrowFunctions'] },
],
'@typescript-eslint/no-non-null-assertion': 'off',
'@typescript-eslint/no-unsafe-assignment': 'off',
'@typescript-eslint/no-unsafe-call': 'off',
'@typescript-eslint/no-unsafe-member-access': 'off',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ function getExpectedIndentForNode(
sourceCodeLines: string[],
): number {
const lineIdx = node.loc.start.line - 1;
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const indent = START_OF_LINE_WHITESPACE_MATCHER.exec(
sourceCodeLines[lineIdx],
)![1];
Expand Down Expand Up @@ -348,6 +349,7 @@ export default createRule<Options, MessageIds>({
// +2 because we expect the string contents are indented one level
const expectedIndent = parentIndent + 2;

// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const firstLineIndent = START_OF_LINE_WHITESPACE_MATCHER.exec(
lines[0],
)![1];
Expand All @@ -370,6 +372,7 @@ export default createRule<Options, MessageIds>({
continue;
}

// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const matches = START_OF_LINE_WHITESPACE_MATCHER.exec(line)!;

const indent = matches[1];
Expand Down
1 change: 1 addition & 0 deletions packages/eslint-plugin/src/rules/ban-ts-comment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ export default createRule<[Options], MessageIds>({
if (!match) {
return;
}
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const { directive, description } = match.groups!;

const fullDirective = `ts-${directive}` as keyof Options;
Expand Down
1 change: 1 addition & 0 deletions packages/eslint-plugin/src/rules/block-spacing.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import type { TSESTree } from '@typescript-eslint/utils';
import { AST_TOKEN_TYPES } from '@typescript-eslint/utils';

Expand Down
1 change: 1 addition & 0 deletions packages/eslint-plugin/src/rules/brace-style.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import type { TSESTree } from '@typescript-eslint/utils';

import type {
Expand Down
1 change: 1 addition & 0 deletions packages/eslint-plugin/src/rules/comma-spacing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ export default createRule<Options, MessageIds>({
for (const element of node.elements) {
let token: TSESTree.Token | null;
if (element == null) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
token = context.sourceCode.getTokenAfter(previousToken!);
if (token && isCommaToken(token)) {
ignoredTokens.add(token);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { TSESTree } from '@typescript-eslint/utils';
import { AST_NODE_TYPES } from '@typescript-eslint/utils';

import { createRule } from '../util';
import { createRule, nullThrows, NullThrowsReasons } from '../util';

type MessageIds = 'preferConstructor' | 'preferTypeAnnotation';
type Options = ['constructor' | 'type-annotation'];
Expand Down Expand Up @@ -94,7 +94,10 @@ export default createRule<Options, MessageIds>({
}
// If the property's computed, we have to attach the
// annotation after the square bracket, not the enclosed expression
return context.sourceCode.getTokenAfter(node.key)!;
return nullThrows(
context.sourceCode.getTokenAfter(node.key),
NullThrowsReasons.MissingToken(']', 'key'),
);
Comment on lines +97 to +100
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this pattern is so common - i wonder if we should create a utility to wrap it up and make it even shorter?

eg getRequiredTokenAfter(sourceCode, node.key, 'optional message')

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like it!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, tried this out - but in order to get the same precision of logs we'd need to still pass in ']' and key as well.

return getRequiredTokenAfter(
  context.sourceCode,
  node.key,
  ']',
  'key',
);

I feel like I'd rather get this merged in now, then look at more options in a followup. WDYT?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we should just say "fuck it" and create an API without the message.
It makes the end user experience worse cos more vague error messages - but it would be much cleaner and better devx.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really mind having the extra verbosity for our devx, personally. It's been forcing me to think more carefully about what we're actually asserting on.

}
return [
fixer.remove(typeArguments),
Expand Down
18 changes: 10 additions & 8 deletions packages/eslint-plugin/src/rules/consistent-type-assertions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import {
isClosingParenToken,
isOpeningParenToken,
isParenthesized,
nullThrows,
NullThrowsReasons,
} from '../util';
import { getWrappedCode } from '../util/getWrappedCode';

Expand Down Expand Up @@ -109,14 +111,14 @@ export default createRule<Options, MessageIds>({
let afterCount = 0;

if (isParenthesized(node, context.sourceCode)) {
const bodyOpeningParen = context.sourceCode.getTokenBefore(
node,
isOpeningParenToken,
)!;
const bodyClosingParen = context.sourceCode.getTokenAfter(
node,
isClosingParenToken,
)!;
const bodyOpeningParen = nullThrows(
context.sourceCode.getTokenBefore(node, isOpeningParenToken),
NullThrowsReasons.MissingToken('(', 'node'),
);
const bodyClosingParen = nullThrows(
context.sourceCode.getTokenAfter(node, isClosingParenToken),
NullThrowsReasons.MissingToken(')', 'node'),
);

beforeCount = node.range[0] - bodyOpeningParen.range[0];
afterCount = bodyClosingParen.range[1] - node.range[1];
Expand Down
21 changes: 17 additions & 4 deletions packages/eslint-plugin/src/rules/consistent-type-imports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -529,7 +529,10 @@ export default createRule<Options, MessageIds>({
const last = namedSpecifierGroup[namedSpecifierGroup.length - 1];
const removeRange: TSESTree.Range = [first.range[0], last.range[1]];
const textRange: TSESTree.Range = [...removeRange];
const before = context.sourceCode.getTokenBefore(first)!;
const before = nullThrows(
context.sourceCode.getTokenBefore(first),
NullThrowsReasons.MissingToken('token', 'first specifier'),
);
textRange[0] = before.range[1];
if (isCommaToken(before)) {
removeRange[0] = before.range[0];
Expand All @@ -539,7 +542,10 @@ export default createRule<Options, MessageIds>({

const isFirst = allNamedSpecifiers[0] === first;
const isLast = allNamedSpecifiers[allNamedSpecifiers.length - 1] === last;
const after = context.sourceCode.getTokenAfter(last)!;
const after = nullThrows(
context.sourceCode.getTokenAfter(last),
NullThrowsReasons.MissingToken('token', 'last specifier'),
);
textRange[1] = after.range[0];
if (isFirst || isLast) {
if (isCommaToken(after)) {
Expand All @@ -566,13 +572,20 @@ export default createRule<Options, MessageIds>({
): TSESLint.RuleFix {
const closingBraceToken = nullThrows(
context.sourceCode.getFirstTokenBetween(
context.sourceCode.getFirstToken(target)!,
nullThrows(
context.sourceCode.getFirstToken(target),
NullThrowsReasons.MissingToken('token before', 'import'),
),
target.source,
isClosingBraceToken,
),
NullThrowsReasons.MissingToken('}', target.type),
);
const before = context.sourceCode.getTokenBefore(closingBraceToken)!;
const before = nullThrows(
context.sourceCode.getTokenBefore(closingBraceToken),
NullThrowsReasons.MissingToken('token before', 'closing brace'),
);

if (!isCommaToken(before) && !isOpeningBraceToken(before)) {
insertText = `,${insertText}`;
}
Expand Down
5 changes: 4 additions & 1 deletion packages/eslint-plugin/src/rules/enum-utils/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,15 @@ import { isTypeFlagSet } from '../../util';
* - `Fruit.Apple` --> `Fruit`
*/
function getBaseEnumType(typeChecker: ts.TypeChecker, type: ts.Type): ts.Type {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const symbol = type.getSymbol()!;
if (!tsutils.isSymbolFlagSet(symbol, ts.SymbolFlags.EnumMember)) {
return type;
}

return typeChecker.getTypeAtLocation(symbol.valueDeclaration!.parent);
return typeChecker.getTypeAtLocation(
(symbol.valueDeclaration as ts.EnumMember).parent,
);
}

/**
Expand Down
16 changes: 12 additions & 4 deletions packages/eslint-plugin/src/rules/explicit-member-accessibility.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import type { TSESLint, TSESTree } from '@typescript-eslint/utils';
import { AST_NODE_TYPES, AST_TOKEN_TYPES } from '@typescript-eslint/utils';

import { createRule, getNameFromMember } from '../util';
import {
createRule,
getNameFromMember,
nullThrows,
NullThrowsReasons,
} from '../util';

type AccessibilityLevel =
| 'explicit' // require an accessor (including public)
Expand Down Expand Up @@ -182,7 +187,7 @@ export default createRule<Options, MessageIds>({
): TSESLint.ReportFixFunction {
return function (fixer: TSESLint.RuleFixer): TSESLint.RuleFix {
const tokens = context.sourceCode.getTokens(node);
let rangeToRemove: TSESLint.AST.Range;
let rangeToRemove!: TSESLint.AST.Range;
for (let i = 0; i < tokens.length; i++) {
const token = tokens[i];
if (
Expand All @@ -207,7 +212,7 @@ export default createRule<Options, MessageIds>({
}
}
}
return fixer.removeRange(rangeToRemove!);
return fixer.removeRange(rangeToRemove);
};
}

Expand All @@ -228,7 +233,10 @@ export default createRule<Options, MessageIds>({
): TSESLint.RuleFix | null {
if (node.decorators.length) {
const lastDecorator = node.decorators[node.decorators.length - 1];
const nextToken = context.sourceCode.getTokenAfter(lastDecorator)!;
const nextToken = nullThrows(
context.sourceCode.getTokenAfter(lastDecorator),
NullThrowsReasons.MissingToken('token', 'last decorator'),
);
return fixer.insertTextBefore(nextToken, `${accessibility} `);
}
return fixer.insertTextBefore(node, `${accessibility} `);
Expand Down
1 change: 1 addition & 0 deletions packages/eslint-plugin/src/rules/func-call-spacing.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import type { TSESTree } from '@typescript-eslint/utils';

import {
Expand Down
1 change: 1 addition & 0 deletions packages/eslint-plugin/src/rules/indent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,7 @@ export default createRule<Options, MessageIds>({
},

TSMappedType(node: TSESTree.TSMappedType) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const squareBracketStart = context.sourceCode.getTokenBefore(
node.typeParameter,
)!;
Expand Down
1 change: 1 addition & 0 deletions packages/eslint-plugin/src/rules/key-spacing.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import type { TSESTree } from '@typescript-eslint/utils';
import { AST_NODE_TYPES } from '@typescript-eslint/utils';

Expand Down
1 change: 1 addition & 0 deletions packages/eslint-plugin/src/rules/keyword-spacing.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import type { TSESTree } from '@typescript-eslint/utils';
import { AST_NODE_TYPES, AST_TOKEN_TYPES } from '@typescript-eslint/utils';
import type { JSONSchema4 } from '@typescript-eslint/utils/json-schema';
Expand Down
1 change: 1 addition & 0 deletions packages/eslint-plugin/src/rules/lines-around-comment.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import type { TSESTree } from '@typescript-eslint/utils';
import { AST_NODE_TYPES, AST_TOKEN_TYPES } from '@typescript-eslint/utils';

Expand Down
4 changes: 4 additions & 0 deletions packages/eslint-plugin/src/rules/member-ordering.ts
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,7 @@ function getRankOrder(
const stack = memberGroups.slice(); // Get a copy of the member groups

while (stack.length > 0 && rank === -1) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const memberGroup = stack.shift()!;
rank = orderConfig.findIndex(memberType =>
Array.isArray(memberType)
Expand Down Expand Up @@ -993,6 +994,8 @@ export default createRule<Options, MessageIds>({
}
}

// https://github.com/typescript-eslint/typescript-eslint/issues/5439
/* eslint-disable @typescript-eslint/no-non-null-assertion */
return {
ClassDeclaration(node): void {
validateMembersOrder(
Expand Down Expand Up @@ -1023,5 +1026,6 @@ export default createRule<Options, MessageIds>({
);
},
};
/* eslint-enable @typescript-eslint/no-non-null-assertion */
},
});
Loading