@typescript-eslint/eslint-plugin
Advanced tools
Comparing version 6.9.1 to 6.13.2
@@ -128,2 +128,3 @@ "use strict"; | ||
'@typescript-eslint/no-unsafe-return': 'error', | ||
'@typescript-eslint/no-unsafe-unary-minus': 'error', | ||
'no-unused-expressions': 'off', | ||
@@ -130,0 +131,0 @@ '@typescript-eslint/no-unused-expressions': 'error', |
@@ -7,21 +7,21 @@ "use strict"; | ||
rules: { | ||
'constructor-super': 'off', | ||
'getter-return': 'off', | ||
'no-const-assign': 'off', | ||
'no-dupe-args': 'off', | ||
'no-dupe-class-members': 'off', | ||
'no-dupe-keys': 'off', | ||
'no-func-assign': 'off', | ||
'no-import-assign': 'off', | ||
'no-new-symbol': 'off', | ||
'no-obj-calls': 'off', | ||
'no-redeclare': 'off', | ||
'no-setter-return': 'off', | ||
'no-this-before-super': 'off', | ||
'no-undef': 'off', | ||
'no-unreachable': 'off', | ||
'no-unsafe-negation': 'off', | ||
'no-var': 'error', | ||
'prefer-const': 'error', | ||
'prefer-rest-params': 'error', | ||
'constructor-super': 'off', // ts(2335) & ts(2377) | ||
'getter-return': 'off', // ts(2378) | ||
'no-const-assign': 'off', // ts(2588) | ||
'no-dupe-args': 'off', // ts(2300) | ||
'no-dupe-class-members': 'off', // ts(2393) & ts(2300) | ||
'no-dupe-keys': 'off', // ts(1117) | ||
'no-func-assign': 'off', // ts(2630) | ||
'no-import-assign': 'off', // ts(2632) & ts(2540) | ||
'no-new-symbol': 'off', // ts(7009) | ||
'no-obj-calls': 'off', // ts(2349) | ||
'no-redeclare': 'off', // ts(2451) | ||
'no-setter-return': 'off', // ts(2408) | ||
'no-this-before-super': 'off', // ts(2376) & ts(17009) | ||
'no-undef': 'off', // ts(2304) & ts(2552) | ||
'no-unreachable': 'off', // ts(7027) | ||
'no-unsafe-negation': 'off', // ts(2365) & ts(2322) & ts(2358) | ||
'no-var': 'error', // ts transpiles let/const to var, so no need for vars any more | ||
'prefer-const': 'error', // ts provides better types with const | ||
'prefer-rest-params': 'error', // ts provides better types with rest args over arguments | ||
'prefer-spread': 'error', // ts transpiles spread to apply, so no need for manual apply | ||
@@ -28,0 +28,0 @@ }, |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const util_1 = require("../util"); | ||
@@ -20,3 +21,3 @@ exports.default = (0, util_1.createRule)({ | ||
create(context) { | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
/** | ||
@@ -28,5 +29,2 @@ * Gets the name and attribute of the member being processed. | ||
function getMemberMethod(member) { | ||
if (!member) { | ||
return null; | ||
} | ||
const isStatic = 'static' in member && !!member.static; | ||
@@ -110,27 +108,25 @@ switch (member.type) { | ||
const members = getMembers(node); | ||
if (members) { | ||
let lastMethod = null; | ||
const seenMethods = []; | ||
members.forEach(member => { | ||
const method = getMemberMethod(member); | ||
if (method == null) { | ||
lastMethod = null; | ||
return; | ||
} | ||
const index = seenMethods.findIndex(seenMethod => isSameMethod(method, seenMethod)); | ||
if (index > -1 && !isSameMethod(method, lastMethod)) { | ||
context.report({ | ||
node: member, | ||
messageId: 'adjacentSignature', | ||
data: { | ||
name: `${method.static ? 'static ' : ''}${method.name}`, | ||
}, | ||
}); | ||
} | ||
else if (index === -1) { | ||
seenMethods.push(method); | ||
} | ||
lastMethod = method; | ||
}); | ||
} | ||
let lastMethod = null; | ||
const seenMethods = []; | ||
members.forEach(member => { | ||
const method = getMemberMethod(member); | ||
if (method == null) { | ||
lastMethod = null; | ||
return; | ||
} | ||
const index = seenMethods.findIndex(seenMethod => isSameMethod(method, seenMethod)); | ||
if (index > -1 && !isSameMethod(method, lastMethod)) { | ||
context.report({ | ||
node: member, | ||
messageId: 'adjacentSignature', | ||
data: { | ||
name: `${method.static ? 'static ' : ''}${method.name}`, | ||
}, | ||
}); | ||
} | ||
else if (index === -1) { | ||
seenMethods.push(method); | ||
} | ||
lastMethod = method; | ||
}); | ||
} | ||
@@ -137,0 +133,0 @@ return { |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const util_1 = require("../util"); | ||
@@ -29,4 +30,3 @@ /** | ||
case utils_1.AST_NODE_TYPES.TSTypeReference: | ||
if (node.typeName && | ||
node.typeName.type === utils_1.AST_NODE_TYPES.Identifier && | ||
if (node.typeName.type === utils_1.AST_NODE_TYPES.Identifier && | ||
node.typeName.name === 'Array') { | ||
@@ -116,3 +116,3 @@ if (!node.typeArguments) { | ||
create(context, [options]) { | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
const defaultOption = options.default; | ||
@@ -124,3 +124,3 @@ const readonlyOption = options.readonly ?? defaultOption; | ||
function getMessageType(node) { | ||
if (node && isSimpleType(node)) { | ||
if (isSimpleType(node)) { | ||
return sourceCode.getText(node); | ||
@@ -202,3 +202,3 @@ } | ||
const parentParens = readonlyPrefix && | ||
node.parent?.type === utils_1.AST_NODE_TYPES.TSArrayType && | ||
node.parent.type === utils_1.AST_NODE_TYPES.TSArrayType && | ||
!(0, util_1.isParenthesized)(node.parent.elementType, sourceCode); | ||
@@ -205,0 +205,0 @@ const start = `${parentParens ? '(' : ''}${readonlyPrefix}${typeParens ? '(' : ''}`; |
@@ -26,2 +26,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const tsutils = __importStar(require("ts-api-utils")); | ||
@@ -64,3 +65,3 @@ const util_1 = require("../util"); | ||
fix(fixer) { | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
const awaitKeyword = (0, util_1.nullThrows)(sourceCode.getFirstToken(node, util_1.isAwaitKeyword), util_1.NullThrowsReasons.MissingToken('await', 'await expression')); | ||
@@ -67,0 +68,0 @@ return fixer.remove(awaitKeyword); |
@@ -5,2 +5,3 @@ "use strict"; | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const util_1 = require("../util"); | ||
@@ -18,5 +19,8 @@ exports.defaultMinimumDescriptionLength = 3; | ||
tsDirectiveComment: 'Do not use "@ts-{{directive}}" because it alters compilation errors.', | ||
tsIgnoreInsteadOfExpectError: 'Use "@ts-expect-error" instead of "@ts-ignore", as "@ts-ignore" will do nothing if the following line is error-free.', | ||
tsDirectiveCommentRequiresDescription: 'Include a description after the "@ts-{{directive}}" directive to explain why the @ts-{{directive}} is necessary. The description must be {{minimumDescriptionLength}} characters or longer.', | ||
tsDirectiveCommentDescriptionNotMatchPattern: 'The description for the "@ts-{{directive}}" directive must match the {{format}} format.', | ||
replaceTsIgnoreWithTsExpectError: 'Replace "@ts-ignore" with "@ts-expect-error".', | ||
}, | ||
hasSuggestions: true, | ||
schema: [ | ||
@@ -76,3 +80,3 @@ { | ||
const commentDirectiveRegExMultiLine = /^\s*(?:\/|\*)*\s*@ts-(?<directive>expect-error|ignore|check|nocheck)(?<description>.*)/; | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
const descriptionFormats = new Map(); | ||
@@ -105,7 +109,27 @@ for (const directive of [ | ||
if (option === true) { | ||
context.report({ | ||
data: { directive }, | ||
node: comment, | ||
messageId: 'tsDirectiveComment', | ||
}); | ||
if (directive === 'ignore') { | ||
// Special case to suggest @ts-expect-error instead of @ts-ignore | ||
context.report({ | ||
node: comment, | ||
messageId: 'tsIgnoreInsteadOfExpectError', | ||
suggest: [ | ||
{ | ||
messageId: 'replaceTsIgnoreWithTsExpectError', | ||
fix(fixer) { | ||
const commentText = comment.value.replace(/@ts-ignore/, '@ts-expect-error'); | ||
return fixer.replaceText(comment, comment.type === utils_1.AST_TOKEN_TYPES.Line | ||
? `//${commentText}` | ||
: `/*${commentText}*/`); | ||
}, | ||
}, | ||
], | ||
}); | ||
} | ||
else { | ||
context.report({ | ||
data: { directive }, | ||
node: comment, | ||
messageId: 'tsDirectiveComment', | ||
}); | ||
} | ||
} | ||
@@ -112,0 +136,0 @@ if (option === 'allow-with-description' || |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const util_1 = require("../util"); | ||
@@ -27,3 +28,3 @@ // tslint regex | ||
create: context => { | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
return { | ||
@@ -30,0 +31,0 @@ Program() { |
@@ -5,2 +5,3 @@ "use strict"; | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const util_1 = require("../util"); | ||
@@ -176,3 +177,3 @@ function removeSpaces(str) { | ||
const bannedTypes = new Map(Object.entries(types).map(([type, data]) => [removeSpaces(type), data])); | ||
function checkBannedTypes(typeNode, name = stringifyNode(typeNode, context.getSourceCode())) { | ||
function checkBannedTypes(typeNode, name = stringifyNode(typeNode, (0, eslint_utils_1.getSourceCode)(context))) { | ||
const bannedType = bannedTypes.get(name); | ||
@@ -179,0 +180,0 @@ if (bannedType === undefined || bannedType === false) { |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const util_1 = require("../util"); | ||
@@ -22,3 +23,3 @@ const getESLintCoreRule_1 = require("../util/getESLintCoreRule"); | ||
create(context, [whenToApplyOption]) { | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
const baseRules = baseRule.create(context); | ||
@@ -67,4 +68,3 @@ const always = whenToApplyOption !== 'never'; | ||
// Skip if the node is invalid or empty. | ||
if (openBrace.type !== utils_1.AST_TOKEN_TYPES.Punctuator || | ||
openBrace.value !== '{' || | ||
if (openBrace.value !== '{' || | ||
closeBrace.type !== utils_1.AST_TOKEN_TYPES.Punctuator || | ||
@@ -71,0 +71,0 @@ closeBrace.value !== '}' || |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const util_1 = require("../util"); | ||
@@ -25,3 +26,3 @@ const getESLintCoreRule_1 = require("../util/getESLintCoreRule"); | ||
const isAllmanStyle = style === 'allman'; | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
const rules = baseRule.create(context); | ||
@@ -28,0 +29,0 @@ /** |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const util_1 = require("../util"); | ||
@@ -63,3 +64,3 @@ const printNodeModifiers = (node, final) => `${node.accessibility ?? ''}${node.static ? ' static' : ''} ${final} `.trimStart(); | ||
fix(fixer) { | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
const name = sourceCode.getText(node.key); | ||
@@ -93,3 +94,3 @@ let text = ''; | ||
fix(fixer) { | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
const name = sourceCode.getText(node.key); | ||
@@ -96,0 +97,0 @@ let text = ''; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const util_1 = require("../util"); | ||
@@ -37,3 +38,13 @@ exports.default = (0, util_1.createRule)({ | ||
ignoreClassesThatImplementAnInterface: { | ||
type: 'boolean', | ||
oneOf: [ | ||
{ | ||
type: 'boolean', | ||
description: 'Ignore all classes that implement an interface', | ||
}, | ||
{ | ||
type: 'string', | ||
enum: ['public-fields'], | ||
description: 'Ignore only the public fields of classes that implement an interface', | ||
}, | ||
], | ||
description: 'Ignore classes that specifically implement some interface', | ||
@@ -60,3 +71,3 @@ }, | ||
let stack; | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
function pushContext(member) { | ||
@@ -97,2 +108,8 @@ if (member?.parent.type === utils_1.AST_NODE_TYPES.ClassBody) { | ||
} | ||
function isPublicField(accessibility) { | ||
if (!accessibility || accessibility === 'public') { | ||
return true; | ||
} | ||
return false; | ||
} | ||
/** | ||
@@ -126,7 +143,9 @@ * Check if the node is an instance method not excluded by config | ||
if (stackContext?.member == null || | ||
stackContext.class == null || | ||
stackContext.usesThis || | ||
(ignoreOverrideMethods && stackContext.member.override) || | ||
(ignoreClassesThatImplementAnInterface && | ||
stackContext.class.implements != null)) { | ||
(ignoreClassesThatImplementAnInterface === true && | ||
stackContext.class.implements.length > 0) || | ||
(ignoreClassesThatImplementAnInterface === 'public-fields' && | ||
stackContext.class.implements.length > 0 && | ||
isPublicField(stackContext.member.accessibility))) { | ||
return; | ||
@@ -133,0 +152,0 @@ } |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const util_1 = require("../util"); | ||
@@ -80,3 +81,3 @@ const getESLintCoreRule_1 = require("../util/getESLintCoreRule"); | ||
const rules = baseRule.create(context); | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
const normalizedOptions = normalizeOptions(options); | ||
@@ -83,0 +84,0 @@ const predicate = { |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const util_1 = require("../util"); | ||
@@ -42,3 +43,3 @@ exports.default = (0, util_1.createRule)({ | ||
create(context, [{ before: spaceBefore, after: spaceAfter }]) { | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
const tokensAndComments = sourceCode.tokensAndComments; | ||
@@ -139,3 +140,3 @@ const ignoredTokens = new Set(); | ||
const prevToken = tokensAndComments[i - 1]; | ||
const nextToken = tokensAndComments[i + 1]; | ||
const nextToken = tokensAndComments.at(i + 1); | ||
validateCommaSpacing(token, (0, util_1.isCommaToken)(prevToken) || ignoredTokens.has(token) | ||
@@ -145,3 +146,3 @@ ? null | ||
? null | ||
: nextToken); | ||
: nextToken ?? null); | ||
}); | ||
@@ -148,0 +149,0 @@ }, |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const util_1 = require("../util"); | ||
@@ -27,3 +28,3 @@ exports.default = (0, util_1.createRule)({ | ||
create(context, [mode]) { | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
return { | ||
@@ -84,24 +85,22 @@ 'VariableDeclarator,PropertyDefinition,:matches(FunctionDeclaration,FunctionExpression) > AssignmentPattern'(node) { | ||
} | ||
if (mode === 'constructor') { | ||
if (lhs?.typeArguments && !rhs.typeArguments) { | ||
const hasParens = sourceCode.getTokenAfter(rhs.callee)?.value === '('; | ||
const extraComments = new Set(sourceCode.getCommentsInside(lhs.parent)); | ||
sourceCode | ||
.getCommentsInside(lhs.typeArguments) | ||
.forEach(c => extraComments.delete(c)); | ||
context.report({ | ||
node, | ||
messageId: 'preferConstructor', | ||
*fix(fixer) { | ||
yield fixer.remove(lhs.parent); | ||
for (const comment of extraComments) { | ||
yield fixer.insertTextAfter(rhs.callee, sourceCode.getText(comment)); | ||
} | ||
yield fixer.insertTextAfter(rhs.callee, sourceCode.getText(lhs.typeArguments)); | ||
if (!hasParens) { | ||
yield fixer.insertTextAfter(rhs.callee, '()'); | ||
} | ||
}, | ||
}); | ||
} | ||
if (lhs?.typeArguments && !rhs.typeArguments) { | ||
const hasParens = sourceCode.getTokenAfter(rhs.callee)?.value === '('; | ||
const extraComments = new Set(sourceCode.getCommentsInside(lhs.parent)); | ||
sourceCode | ||
.getCommentsInside(lhs.typeArguments) | ||
.forEach(c => extraComments.delete(c)); | ||
context.report({ | ||
node, | ||
messageId: 'preferConstructor', | ||
*fix(fixer) { | ||
yield fixer.remove(lhs.parent); | ||
for (const comment of extraComments) { | ||
yield fixer.insertTextAfter(rhs.callee, sourceCode.getText(comment)); | ||
} | ||
yield fixer.insertTextAfter(rhs.callee, sourceCode.getText(lhs.typeArguments)); | ||
if (!hasParens) { | ||
yield fixer.insertTextAfter(rhs.callee, '()'); | ||
} | ||
}, | ||
}); | ||
} | ||
@@ -108,0 +107,0 @@ }, |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const util_1 = require("../util"); | ||
@@ -27,3 +28,3 @@ exports.default = (0, util_1.createRule)({ | ||
create(context, [mode]) { | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
function checkMembers(members, node, parentId, prefix, postfix, safeFix = true) { | ||
@@ -37,9 +38,6 @@ if (members.length !== 1) { | ||
} | ||
const [parameter] = member.parameters; | ||
if (!parameter) { | ||
const parameter = member.parameters.at(0); | ||
if (parameter?.type !== utils_1.AST_NODE_TYPES.Identifier) { | ||
return; | ||
} | ||
if (parameter.type !== utils_1.AST_NODE_TYPES.Identifier) { | ||
return; | ||
} | ||
const keyType = parameter.typeAnnotation; | ||
@@ -54,3 +52,3 @@ if (!keyType) { | ||
if (parentId) { | ||
const scope = context.getScope(); | ||
const scope = (0, eslint_utils_1.getScope)(context); | ||
const superVar = utils_1.ASTUtils.findVariable(scope, parentId.name); | ||
@@ -113,3 +111,3 @@ if (superVar) { | ||
let genericTypes = ''; | ||
if (node.typeParameters?.params?.length) { | ||
if (node.typeParameters?.params.length) { | ||
genericTypes = `<${node.typeParameters.params | ||
@@ -119,3 +117,3 @@ .map(p => sourceCode.getText(p)) | ||
} | ||
checkMembers(node.body.body, node, node.id, `type ${node.id.name}${genericTypes} = `, ';', !node.extends?.length); | ||
checkMembers(node.body.body, node, node.id, `type ${node.id.name}${genericTypes} = `, ';', !node.extends.length); | ||
}, | ||
@@ -122,0 +120,0 @@ }), |
@@ -27,2 +27,3 @@ "use strict"; | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const ts = __importStar(require("typescript")); | ||
@@ -89,3 +90,3 @@ const util_1 = require("../util"); | ||
create(context, [options]) { | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
const parserServices = (0, util_1.getParserServices)(context, true); | ||
@@ -176,6 +177,5 @@ function isConst(node) { | ||
} | ||
if (checkType(node.typeAnnotation) && | ||
node.expression.type === utils_1.AST_NODE_TYPES.ObjectExpression) { | ||
if (checkType(node.typeAnnotation)) { | ||
const suggest = []; | ||
if (node.parent?.type === utils_1.AST_NODE_TYPES.VariableDeclarator && | ||
if (node.parent.type === utils_1.AST_NODE_TYPES.VariableDeclarator && | ||
!node.parent.id.typeAnnotation) { | ||
@@ -197,5 +197,3 @@ const { parent } = node; | ||
fixer.replaceText(node, getTextWithParentheses(node.expression)), | ||
fixer.insertTextAfter(node, ` satisfies ${context | ||
.getSourceCode() | ||
.getText(node.typeAnnotation)}`), | ||
fixer.insertTextAfter(node, ` satisfies ${(0, eslint_utils_1.getSourceCode)(context).getText(node.typeAnnotation)}`), | ||
], | ||
@@ -202,0 +200,0 @@ }); |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const util_1 = require("../util"); | ||
@@ -27,3 +28,3 @@ exports.default = (0, util_1.createRule)({ | ||
create(context, [option]) { | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
/** | ||
@@ -34,5 +35,3 @@ * Iterates from the highest parent to the currently traversed node | ||
function isCurrentlyTraversedNodeWithinModuleDeclaration() { | ||
return context | ||
.getAncestors() | ||
.some(node => node.type === utils_1.AST_NODE_TYPES.TSModuleDeclaration && | ||
return (0, eslint_utils_1.getAncestors)(context).some(node => node.type === utils_1.AST_NODE_TYPES.TSModuleDeclaration && | ||
node.declare && | ||
@@ -78,9 +77,7 @@ node.global); | ||
} | ||
if (node.extends) { | ||
node.extends.forEach(heritage => { | ||
const typeIdentifier = sourceCode.getText(heritage); | ||
fixes.push(fixer.insertTextAfter(node.body, ` & ${typeIdentifier}`)); | ||
}); | ||
} | ||
if (node.parent?.type === utils_1.AST_NODE_TYPES.ExportDefaultDeclaration) { | ||
node.extends.forEach(heritage => { | ||
const typeIdentifier = sourceCode.getText(heritage); | ||
fixes.push(fixer.insertTextAfter(node.body, ` & ${typeIdentifier}`)); | ||
}); | ||
if (node.parent.type === utils_1.AST_NODE_TYPES.ExportDefaultDeclaration) { | ||
fixes.push(fixer.removeRange([node.parent.range[0], node.range[0]]), fixer.insertTextAfter(node.body, `\nexport default ${node.id.name}`)); | ||
@@ -87,0 +84,0 @@ } |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const typescript_1 = require("typescript"); | ||
@@ -38,3 +39,3 @@ const util_1 = require("../util"); | ||
create(context, [{ fixMixedExportsWithInlineTypeSpecifier }]) { | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
const sourceExportsMap = {}; | ||
@@ -52,5 +53,8 @@ const services = (0, util_1.getParserServices)(context); | ||
const symbol = services.getSymbolAtLocation(specifier.exported); | ||
if (!symbol) { | ||
return undefined; | ||
} | ||
const aliasedSymbol = checker.getAliasedSymbol(symbol); | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison | ||
if (!aliasedSymbol || aliasedSymbol.escapedName === 'unknown') { | ||
if (aliasedSymbol.escapedName === 'unknown') { | ||
return undefined; | ||
@@ -64,2 +68,3 @@ } | ||
const source = getSourceFromExport(node) ?? 'undefined'; | ||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition | ||
const sourceExports = (sourceExportsMap[source] ||= { | ||
@@ -66,0 +71,0 @@ source, |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const util_1 = require("../util"); | ||
@@ -53,3 +54,3 @@ exports.default = (0, util_1.createRule)({ | ||
const fixStyle = option.fixStyle ?? 'separate-type-imports'; | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
const sourceImportsMap = {}; | ||
@@ -63,7 +64,8 @@ return { | ||
// sourceImports is the object containing all the specifics for a particular import source, type or value | ||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition | ||
sourceImportsMap[source] ??= { | ||
source, | ||
reportValueImports: [], | ||
typeOnlyNamedImport: null, | ||
valueOnlyNamedImport: null, | ||
reportValueImports: [], // if there is a mismatch where type importKind but value specifiers | ||
typeOnlyNamedImport: null, // if only type imports | ||
valueOnlyNamedImport: null, // if only value imports with named specifiers | ||
valueImport: null, // if only value imports | ||
@@ -100,3 +102,3 @@ }; | ||
} | ||
const [variable] = context.getDeclaredVariables(specifier); | ||
const [variable] = (0, eslint_utils_1.getDeclaredVariables)(context, specifier); | ||
if (variable.references.length === 0) { | ||
@@ -112,5 +114,5 @@ unusedSpecifiers.push(specifier); | ||
*/ | ||
if (ref.identifier.parent?.type === | ||
if (ref.identifier.parent.type === | ||
utils_1.AST_NODE_TYPES.ExportSpecifier || | ||
ref.identifier.parent?.type === | ||
ref.identifier.parent.type === | ||
utils_1.AST_NODE_TYPES.ExportDefaultDeclaration) { | ||
@@ -197,3 +199,3 @@ if (ref.isValueReference && ref.isTypeReference) { | ||
*/ | ||
if (report.node.assertions.length === 0) { | ||
if (report.node.attributes.length === 0) { | ||
context.report({ | ||
@@ -431,3 +433,3 @@ node: report.node, | ||
// checks for presence of import assertions | ||
if (node.assertions.length === 0) { | ||
if (node.attributes.length === 0) { | ||
yield* fixInsertTypeSpecifierForImportDeclaration(fixer, node, false); | ||
@@ -434,0 +436,0 @@ } |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const util_1 = require("../util"); | ||
@@ -73,3 +74,3 @@ const explicitReturnTypeUtils_1 = require("../util/explicitReturnTypeUtils"); | ||
create(context, [options]) { | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
function isAllowedFunction(node) { | ||
@@ -92,3 +93,3 @@ if (options.allowFunctionsWithoutTypeParameters && !node.typeParameters) { | ||
} | ||
else if (parent) { | ||
else { | ||
switch (parent.type) { | ||
@@ -118,3 +119,2 @@ case utils_1.AST_NODE_TYPES.VariableDeclarator: { | ||
node.id && | ||
node.id.type === utils_1.AST_NODE_TYPES.Identifier && | ||
!!options.allowedNames.includes(node.id.name)) { | ||
@@ -121,0 +121,0 @@ return true; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const util_1 = require("../util"); | ||
@@ -72,3 +73,3 @@ exports.default = (0, util_1.createRule)({ | ||
create(context, [option]) { | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
const baseCheck = option.accessibility ?? 'explicit'; | ||
@@ -170,3 +171,3 @@ const overrides = option.overrides ?? {}; | ||
function fix(accessibility, fixer) { | ||
if (node?.decorators.length) { | ||
if (node.decorators.length) { | ||
const lastDecorator = node.decorators[node.decorators.length - 1]; | ||
@@ -173,0 +174,0 @@ const nextToken = sourceCode.getTokenAfter(lastDecorator); |
@@ -5,2 +5,3 @@ "use strict"; | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const util_1 = require("../util"); | ||
@@ -70,3 +71,3 @@ const explicitReturnTypeUtils_1 = require("../util/explicitReturnTypeUtils"); | ||
create(context, [options]) { | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
// tracks all of the functions we've already checked | ||
@@ -217,3 +218,3 @@ const checkedFunctions = new Set(); | ||
// the parent of a return will always be a block statement, so we can skip over it | ||
current = current.parent?.parent; | ||
current = current.parent.parent; | ||
continue; | ||
@@ -233,3 +234,3 @@ } | ||
function followReference(node) { | ||
const scope = context.getScope(); | ||
const scope = (0, eslint_utils_1.getScope)(context); | ||
const variable = scope.set.get(node.name); | ||
@@ -318,6 +319,6 @@ /* istanbul ignore if */ if (!variable) { | ||
function checkEmptyBodyFunctionExpression(node) { | ||
const isConstructor = node.parent?.type === utils_1.AST_NODE_TYPES.MethodDefinition && | ||
const isConstructor = node.parent.type === utils_1.AST_NODE_TYPES.MethodDefinition && | ||
node.parent.kind === 'constructor'; | ||
const isSetAccessor = (node.parent?.type === utils_1.AST_NODE_TYPES.TSAbstractMethodDefinition || | ||
node.parent?.type === utils_1.AST_NODE_TYPES.MethodDefinition) && | ||
const isSetAccessor = (node.parent.type === utils_1.AST_NODE_TYPES.TSAbstractMethodDefinition || | ||
node.parent.type === utils_1.AST_NODE_TYPES.MethodDefinition) && | ||
node.parent.kind === 'set'; | ||
@@ -324,0 +325,0 @@ if (!isConstructor && !isSetAccessor && !node.returnType) { |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const util_1 = require("../util"); | ||
@@ -56,3 +57,3 @@ exports.default = (0, util_1.createRule)({ | ||
create(context, [option, config]) { | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
const text = sourceCode.getText(); | ||
@@ -59,0 +60,0 @@ /** |
@@ -10,2 +10,3 @@ "use strict"; | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const util_1 = require("../util"); | ||
@@ -318,3 +319,3 @@ const getESLintCoreRule_1 = require("../util/getESLintCoreRule"); | ||
TSMappedType(node) { | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
const squareBracketStart = sourceCode.getTokenBefore(node.typeParameter); | ||
@@ -321,0 +322,0 @@ // transform it to an ObjectExpression |
@@ -95,2 +95,3 @@ "use strict"; | ||
const no_unsafe_return_1 = __importDefault(require("./no-unsafe-return")); | ||
const no_unsafe_unary_minus_1 = __importDefault(require("./no-unsafe-unary-minus")); | ||
const no_unused_expressions_1 = __importDefault(require("./no-unused-expressions")); | ||
@@ -232,2 +233,3 @@ const no_unused_vars_1 = __importDefault(require("./no-unused-vars")); | ||
'no-unsafe-return': no_unsafe_return_1.default, | ||
'no-unsafe-unary-minus': no_unsafe_unary_minus_1.default, | ||
'no-unused-expressions': no_unused_expressions_1.default, | ||
@@ -234,0 +236,0 @@ 'no-unused-vars': no_unused_vars_1.default, |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const util_1 = require("../util"); | ||
@@ -11,11 +12,2 @@ const getESLintCoreRule_1 = require("../util/getESLintCoreRule"); | ||
: baseRule.meta.schema; | ||
/** | ||
* TODO: replace with native .at() once Node 14 stops being supported | ||
*/ | ||
function at(arr, position) { | ||
if (position < 0) { | ||
return arr[arr.length + position]; | ||
} | ||
return arr[position]; | ||
} | ||
exports.default = (0, util_1.createRule)({ | ||
@@ -36,3 +28,3 @@ name: 'key-spacing', | ||
create(context, [options]) { | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
const baseRules = baseRule.create(context); | ||
@@ -44,3 +36,3 @@ /** | ||
const line = position.line - 1; // position.line is 1-indexed | ||
return (0, util_1.getStringLength)(at(sourceCode.lines, line).slice(0, position.column)); | ||
return (0, util_1.getStringLength)(sourceCode.lines.at(line).slice(0, position.column)); | ||
} | ||
@@ -73,3 +65,3 @@ /** | ||
const code = sourceCode.getText(node); | ||
return code.slice(0, sourceCode.getTokenAfter(at(node.parameters, -1), util_1.isClosingBracketToken).range[1] - node.range[0]); | ||
return code.slice(0, sourceCode.getTokenAfter(node.parameters.at(-1), util_1.isClosingBracketToken).range[1] - node.range[0]); | ||
} | ||
@@ -82,3 +74,3 @@ /** | ||
? node.key | ||
: at(node.parameters, -1)).loc.end; | ||
: node.parameters.at(-1)).loc.end; | ||
} | ||
@@ -158,3 +150,3 @@ function checkBeforeColon(node, expectedWhitespaceBeforeColon, mode) { | ||
leadingComments[0].loc.start.line - groupEndLine <= 1 && | ||
candidateValueStartLine - at(leadingComments, -1).loc.end.line <= 1) { | ||
candidateValueStartLine - leadingComments.at(-1).loc.end.line <= 1) { | ||
for (let i = 1; i < leadingComments.length; i++) { | ||
@@ -292,3 +284,3 @@ if (leadingComments[i].loc.start.line - | ||
for (const node of members) { | ||
let prevAlignedNode = at(currentAlignGroup, -1); | ||
let prevAlignedNode = currentAlignGroup.at(-1); | ||
if (prevAlignedNode !== prevNode) { | ||
@@ -295,0 +287,0 @@ prevAlignedNode = undefined; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const util_1 = require("../util"); | ||
@@ -38,3 +39,3 @@ const getESLintCoreRule_1 = require("../util/getESLintCoreRule"); | ||
create(context, [{ after, overrides }]) { | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
const baseRules = baseRule.create(context); | ||
@@ -60,3 +61,3 @@ return { | ||
const punctuatorToken = sourceCode.getTokenAfter(typeToken); | ||
if (node.specifiers?.[0]?.type === utils_1.AST_NODE_TYPES.ImportDefaultSpecifier) { | ||
if (node.specifiers[0]?.type === utils_1.AST_NODE_TYPES.ImportDefaultSpecifier) { | ||
return; | ||
@@ -63,0 +64,0 @@ } |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const util_1 = require("../util"); | ||
@@ -134,3 +135,3 @@ const getESLintCoreRule_1 = require("../util/getESLintCoreRule"); | ||
const customIgnoreRegExp = new RegExp(options.ignorePattern ?? '', 'u'); | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
const comments = sourceCode.getAllComments(); | ||
@@ -344,9 +345,7 @@ const lines = sourceCode.lines; | ||
} | ||
else if (token.type === utils_1.AST_TOKEN_TYPES.Block) { | ||
if (options.beforeBlockComment || options.afterBlockComment) { | ||
checkForEmptyLine(token, { | ||
after: options.afterBlockComment, | ||
before: options.beforeBlockComment, | ||
}); | ||
} | ||
else if (options.beforeBlockComment || options.afterBlockComment) { | ||
checkForEmptyLine(token, { | ||
after: options.afterBlockComment, | ||
before: options.beforeBlockComment, | ||
}); | ||
} | ||
@@ -353,0 +352,0 @@ }); |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const util_1 = require("../util"); | ||
@@ -130,3 +131,3 @@ const isLastTokenEndOfLine = (token, line) => { | ||
create(context, [options]) { | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
// use the base options as the defaults for the cases | ||
@@ -167,3 +168,3 @@ const baseOptions = options; | ||
const sourceCodeLines = sourceCode.getLines(); | ||
const lastTokenLine = sourceCodeLines[lastToken?.loc.start.line - 1]; | ||
const lastTokenLine = sourceCodeLines[lastToken.loc.start.line - 1]; | ||
const optsSemi = getOption('semi'); | ||
@@ -248,3 +249,3 @@ const optsComma = getOption('comma'); | ||
members.forEach((member, index) => { | ||
checkLastToken(member, opts ?? {}, index === members.length - 1); | ||
checkLastToken(member, opts, index === members.length - 1); | ||
}); | ||
@@ -251,0 +252,0 @@ } |
@@ -8,2 +8,3 @@ "use strict"; | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const natural_compare_1 = __importDefault(require("natural-compare")); | ||
@@ -80,2 +81,25 @@ const util_1 = require("../util"); | ||
'constructor', | ||
// Accessors | ||
'public-static-accessor', | ||
'protected-static-accessor', | ||
'private-static-accessor', | ||
'#private-static-accessor', | ||
'public-decorated-accessor', | ||
'protected-decorated-accessor', | ||
'private-decorated-accessor', | ||
'public-instance-accessor', | ||
'protected-instance-accessor', | ||
'private-instance-accessor', | ||
'#private-instance-accessor', | ||
'public-abstract-accessor', | ||
'protected-abstract-accessor', | ||
'public-accessor', | ||
'protected-accessor', | ||
'private-accessor', | ||
'#private-accessor', | ||
'static-accessor', | ||
'instance-accessor', | ||
'abstract-accessor', | ||
'decorated-accessor', | ||
'accessor', | ||
// Getters | ||
@@ -159,2 +183,3 @@ 'public-static-get', | ||
'constructor', | ||
'accessor', | ||
'get', | ||
@@ -173,3 +198,3 @@ 'set', | ||
} | ||
// Only class instance fields, methods, get and set can have decorators attached to them | ||
// Only class instance fields, methods, accessors, get and set can have decorators attached to them | ||
if (accessibility !== '#private' && | ||
@@ -179,2 +204,3 @@ (type === 'readonly-field' || | ||
type === 'method' || | ||
type === 'accessor' || | ||
type === 'get' || | ||
@@ -228,2 +254,4 @@ type === 'set')) { | ||
return node.readonly ? 'readonly-field' : 'field'; | ||
case utils_1.AST_NODE_TYPES.AccessorProperty: | ||
return 'accessor'; | ||
case utils_1.AST_NODE_TYPES.PropertyDefinition: | ||
@@ -334,3 +362,3 @@ return node.value && functionExpressions.includes(node.value.type) | ||
} | ||
if ('key' in node && node.key?.type === utils_1.AST_NODE_TYPES.PrivateIdentifier) { | ||
if ('key' in node && node.key.type === utils_1.AST_NODE_TYPES.PrivateIdentifier) { | ||
return '#private'; | ||
@@ -538,8 +566,8 @@ } | ||
// Find first member which isn't correctly sorted | ||
members.forEach(member => { | ||
for (const member of members) { | ||
const rank = getRank(member, groupOrder, supportsModifiers); | ||
const name = getMemberName(member, context.getSourceCode()); | ||
const name = getMemberName(member, (0, eslint_utils_1.getSourceCode)(context)); | ||
const rankLastMember = previousRanks[previousRanks.length - 1]; | ||
if (rank === -1) { | ||
return; | ||
continue; | ||
} | ||
@@ -567,3 +595,3 @@ // Works for 1st item because x < undefined === false for any x (typeof string) | ||
} | ||
}); | ||
} | ||
return isCorrectlySorted ? memberGroups : null; | ||
@@ -584,3 +612,3 @@ } | ||
members.forEach(member => { | ||
const name = getMemberName(member, context.getSourceCode()); | ||
const name = getMemberName(member, (0, eslint_utils_1.getSourceCode)(context)); | ||
// Note: Not all members have names | ||
@@ -634,3 +662,3 @@ if (name) { | ||
data: { | ||
member: getMemberName(member, context.getSourceCode()), | ||
member: getMemberName(member, (0, eslint_utils_1.getSourceCode)(context)), | ||
optionalOrRequired: optionalityOrder === 'required-first' ? 'required' : 'optional', | ||
@@ -637,0 +665,0 @@ }, |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const util_1 = require("../util"); | ||
@@ -26,3 +27,3 @@ exports.default = (0, util_1.createRule)({ | ||
create(context, [mode]) { | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
function getMethodKey(node) { | ||
@@ -88,5 +89,5 @@ let key = sourceCode.getText(node.key); | ||
const parent = methodNode.parent; | ||
const members = parent?.type === utils_1.AST_NODE_TYPES.TSInterfaceBody | ||
const members = parent.type === utils_1.AST_NODE_TYPES.TSInterfaceBody | ||
? parent.body | ||
: parent?.type === utils_1.AST_NODE_TYPES.TSTypeLiteral | ||
: parent.type === utils_1.AST_NODE_TYPES.TSTypeLiteral | ||
? parent.members | ||
@@ -93,0 +94,0 @@ : []; |
@@ -107,3 +107,3 @@ "use strict"; | ||
formats: formats?.map(f => enums_1.PredefinedFormats[f]).join(', '), | ||
regex: custom?.regex?.toString(), | ||
regex: custom?.regex.toString(), | ||
regexMatch: custom?.match === true | ||
@@ -110,0 +110,0 @@ ? 'match' |
@@ -5,2 +5,3 @@ "use strict"; | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const util_1 = require("../util"); | ||
@@ -53,4 +54,3 @@ const naming_convention_utils_1 = require("./naming-convention-utils"); | ||
create(contextWithoutDefaults) { | ||
const context = contextWithoutDefaults.options && | ||
contextWithoutDefaults.options.length > 0 | ||
const context = contextWithoutDefaults.options.length > 0 | ||
? contextWithoutDefaults | ||
@@ -64,5 +64,2 @@ : // only apply the defaults when the user provides no config | ||
function handleMember(validator, node, modifiers) { | ||
if (!validator) { | ||
return; | ||
} | ||
const key = node.key; | ||
@@ -101,3 +98,3 @@ if (requiresQuoting(key, compilerOptions.target)) { | ||
const unusedVariables = (0, util_1.collectUnusedVariables)(context); | ||
function isUnused(name, initialScope = context.getScope()) { | ||
function isUnused(name, initialScope = (0, eslint_utils_1.getScope)(context)) { | ||
let variable = null; | ||
@@ -121,7 +118,7 @@ let scope = initialScope; | ||
// does not match `const { x: y }` | ||
(id.parent?.type === utils_1.AST_NODE_TYPES.Property && id.parent.shorthand) || | ||
(id.parent.type === utils_1.AST_NODE_TYPES.Property && id.parent.shorthand) || | ||
// `const { x = 2 }` | ||
// does not match const `{ x: y = 2 }` | ||
(id.parent?.type === utils_1.AST_NODE_TYPES.AssignmentPattern && | ||
id.parent.parent?.type === utils_1.AST_NODE_TYPES.Property && | ||
(id.parent.type === utils_1.AST_NODE_TYPES.AssignmentPattern && | ||
id.parent.parent.type === utils_1.AST_NODE_TYPES.Property && | ||
id.parent.parent.shorthand)); | ||
@@ -136,8 +133,7 @@ } | ||
function isAsyncVariableIdentifier(id) { | ||
return Boolean(id.parent && | ||
(('async' in id.parent && id.parent.async) || | ||
('init' in id.parent && | ||
id.parent.init && | ||
'async' in id.parent.init && | ||
id.parent.init.async))); | ||
return Boolean(('async' in id.parent && id.parent.async) || | ||
('init' in id.parent && | ||
id.parent.init && | ||
'async' in id.parent.init && | ||
id.parent.init.async)); | ||
} | ||
@@ -176,7 +172,7 @@ const selectors = { | ||
const parent = node.parent; | ||
if (parent?.type === utils_1.AST_NODE_TYPES.VariableDeclaration) { | ||
if (parent.type === utils_1.AST_NODE_TYPES.VariableDeclaration) { | ||
if (parent.kind === 'const') { | ||
baseModifiers.add(naming_convention_utils_1.Modifiers.const); | ||
} | ||
if (isGlobal(context.getScope())) { | ||
if (isGlobal((0, eslint_utils_1.getScope)(context))) { | ||
baseModifiers.add(naming_convention_utils_1.Modifiers.global); | ||
@@ -190,3 +186,3 @@ } | ||
} | ||
if (isExported(parent, id.name, context.getScope())) { | ||
if (isExported(parent, id.name, (0, eslint_utils_1.getScope)(context))) { | ||
modifiers.add(naming_convention_utils_1.Modifiers.exported); | ||
@@ -214,3 +210,3 @@ } | ||
// functions create their own nested scope | ||
const scope = context.getScope().upper; | ||
const scope = (0, eslint_utils_1.getScope)(context).upper; | ||
if (isGlobal(scope)) { | ||
@@ -374,3 +370,3 @@ modifiers.add(naming_convention_utils_1.Modifiers.global); | ||
// classes create their own nested scope | ||
const scope = context.getScope().upper; | ||
const scope = (0, eslint_utils_1.getScope)(context).upper; | ||
if (node.abstract) { | ||
@@ -394,3 +390,3 @@ modifiers.add(naming_convention_utils_1.Modifiers.abstract); | ||
const modifiers = new Set(); | ||
const scope = context.getScope(); | ||
const scope = (0, eslint_utils_1.getScope)(context); | ||
if (isExported(node, node.id.name, scope)) { | ||
@@ -411,3 +407,3 @@ modifiers.add(naming_convention_utils_1.Modifiers.exported); | ||
const modifiers = new Set(); | ||
const scope = context.getScope(); | ||
const scope = (0, eslint_utils_1.getScope)(context); | ||
if (isExported(node, node.id.name, scope)) { | ||
@@ -429,3 +425,3 @@ modifiers.add(naming_convention_utils_1.Modifiers.exported); | ||
// enums create their own nested scope | ||
const scope = context.getScope().upper; | ||
const scope = (0, eslint_utils_1.getScope)(context).upper; | ||
if (isExported(node, node.id.name, scope)) { | ||
@@ -446,3 +442,3 @@ modifiers.add(naming_convention_utils_1.Modifiers.exported); | ||
const modifiers = new Set(); | ||
const scope = context.getScope(); | ||
const scope = (0, eslint_utils_1.getScope)(context); | ||
if (isUnused(node.name.name, scope)) { | ||
@@ -456,4 +452,3 @@ modifiers.add(naming_convention_utils_1.Modifiers.unused); | ||
}; | ||
return Object.fromEntries(Object.entries(selectors) | ||
.map(([selector, { validator, handler }]) => { | ||
return Object.fromEntries(Object.entries(selectors).map(([selector, { validator, handler }]) => { | ||
return [ | ||
@@ -465,4 +460,3 @@ selector, | ||
]; | ||
}) | ||
.filter((s) => s != null)); | ||
})); | ||
}, | ||
@@ -488,4 +482,4 @@ }); | ||
const refParent = ref.identifier.parent; | ||
if (refParent?.type === utils_1.AST_NODE_TYPES.ExportDefaultDeclaration || | ||
refParent?.type === utils_1.AST_NODE_TYPES.ExportSpecifier) { | ||
if (refParent.type === utils_1.AST_NODE_TYPES.ExportDefaultDeclaration || | ||
refParent.type === utils_1.AST_NODE_TYPES.ExportSpecifier) { | ||
return true; | ||
@@ -492,0 +486,0 @@ } |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const util_1 = require("../util"); | ||
@@ -39,3 +40,3 @@ exports.default = (0, util_1.createRule)({ | ||
} | ||
const fullText = context.getSourceCode().getText(node); | ||
const fullText = (0, eslint_utils_1.getSourceCode)(context).getText(node); | ||
const preambleLength = node.callee.range[1] - node.range[0]; | ||
@@ -42,0 +43,0 @@ return fixer.replaceText(node, `[${fullText.slice(preambleLength + 1, -1)}]`); |
@@ -27,2 +27,3 @@ "use strict"; | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const ts = __importStar(require("typescript")); | ||
@@ -83,3 +84,3 @@ const util_1 = require("../util"); | ||
certainty, | ||
name: context.getSourceCode().getText(node), | ||
name: (0, eslint_utils_1.getSourceCode)(context).getText(node), | ||
}, | ||
@@ -86,0 +87,0 @@ messageId: 'baseToString', |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const util_1 = require("../util"); | ||
@@ -26,3 +27,3 @@ exports.default = (0, util_1.createRule)({ | ||
create(context) { | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
return { | ||
@@ -40,3 +41,3 @@ 'BinaryExpression, AssignmentExpression'(node) { | ||
if (leftHandFinalToken?.type === utils_1.AST_TOKEN_TYPES.Punctuator && | ||
leftHandFinalToken?.value === '!' && | ||
leftHandFinalToken.value === '!' && | ||
tokenAfterLeft?.value !== ')') { | ||
@@ -43,0 +44,0 @@ if (isLeftHandPrimaryExpression(node.left)) { |
@@ -27,2 +27,3 @@ "use strict"; | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const tsutils = __importStar(require("ts-api-utils")); | ||
@@ -86,3 +87,3 @@ const ts = __importStar(require("typescript")); | ||
} | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
const wrapVoidFix = (fixer) => { | ||
@@ -89,0 +90,0 @@ const nodeText = sourceCode.getText(node); |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const util_1 = require("../util"); | ||
@@ -97,3 +98,3 @@ const astIgnoreKeys = new Set(['range', 'loc', 'parent']); | ||
function reportDuplicate(duplicateConstituent, parentNode) { | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
const beforeTokens = sourceCode.getTokensBefore(duplicateConstituent.duplicated, { filter: token => token.value === '|' || token.value === '&' }); | ||
@@ -100,0 +101,0 @@ const beforeUnionOrIntersectionToken = beforeTokens[beforeTokens.length - 1]; |
@@ -27,2 +27,3 @@ "use strict"; | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const tsutils = __importStar(require("ts-api-utils")); | ||
@@ -71,3 +72,3 @@ const util_1 = require("../util"); | ||
function getTokenRange(property) { | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
return [ | ||
@@ -74,0 +75,0 @@ sourceCode.getTokenBefore(property).range[0], |
@@ -67,3 +67,3 @@ "use strict"; | ||
function isBodyEmpty(node) { | ||
return !node.body || node.body.body.length === 0; | ||
return node.body.body.length === 0; | ||
} | ||
@@ -77,3 +77,3 @@ /** | ||
function hasParameterProperties(node) { | ||
return node.params?.some(param => param.type === utils_1.AST_NODE_TYPES.TSParameterProperty); | ||
return node.params.some(param => param.type === utils_1.AST_NODE_TYPES.TSParameterProperty); | ||
} | ||
@@ -88,3 +88,3 @@ /** | ||
if (isBodyEmpty(node) && | ||
parent?.type === utils_1.AST_NODE_TYPES.MethodDefinition && | ||
parent.type === utils_1.AST_NODE_TYPES.MethodDefinition && | ||
parent.kind === 'constructor') { | ||
@@ -109,3 +109,3 @@ const { accessibility } = parent; | ||
if (isAllowedDecoratedFunctions && isBodyEmpty(node)) { | ||
const decorators = node.parent?.type === utils_1.AST_NODE_TYPES.MethodDefinition | ||
const decorators = node.parent.type === utils_1.AST_NODE_TYPES.MethodDefinition | ||
? node.parent.decorators | ||
@@ -120,3 +120,3 @@ : undefined; | ||
isBodyEmpty(node) && | ||
node.parent?.type === utils_1.AST_NODE_TYPES.MethodDefinition && | ||
node.parent.type === utils_1.AST_NODE_TYPES.MethodDefinition && | ||
node.parent.override); | ||
@@ -123,0 +123,0 @@ } |
@@ -5,2 +5,3 @@ "use strict"; | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const util_1 = require("../util"); | ||
@@ -41,4 +42,4 @@ exports.default = (0, util_1.createRule)({ | ||
TSInterfaceDeclaration(node) { | ||
const sourceCode = context.getSourceCode(); | ||
const filename = context.getFilename(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
const filename = (0, eslint_utils_1.getFilename)(context); | ||
if (node.body.body.length !== 0) { | ||
@@ -49,3 +50,3 @@ // interface contains members --> Nothing to report | ||
const extend = node.extends; | ||
if (!extend || extend.length === 0) { | ||
if (extend.length === 0) { | ||
context.report({ | ||
@@ -66,6 +67,6 @@ node: node.id, | ||
}; | ||
const scope = context.getScope(); | ||
const scope = (0, eslint_utils_1.getScope)(context); | ||
const mergedWithClassDeclaration = scope.set | ||
.get(node.id.name) | ||
?.defs?.some(def => def.node.type === utils_1.AST_NODE_TYPES.ClassDeclaration); | ||
?.defs.some(def => def.node.type === utils_1.AST_NODE_TYPES.ClassDeclaration); | ||
const isInAmbientDeclaration = !!((0, util_1.isDefinitionFile)(filename) && | ||
@@ -72,0 +73,0 @@ scope.type === scope_manager_1.ScopeType.tsModule && |
@@ -52,11 +52,11 @@ "use strict"; | ||
return [ | ||
utils_1.AST_NODE_TYPES.ArrowFunctionExpression, | ||
utils_1.AST_NODE_TYPES.FunctionDeclaration, | ||
utils_1.AST_NODE_TYPES.FunctionExpression, | ||
utils_1.AST_NODE_TYPES.TSEmptyBodyFunctionExpression, | ||
utils_1.AST_NODE_TYPES.TSFunctionType, | ||
utils_1.AST_NODE_TYPES.TSConstructorType, | ||
utils_1.AST_NODE_TYPES.TSCallSignatureDeclaration, | ||
utils_1.AST_NODE_TYPES.TSConstructSignatureDeclaration, | ||
utils_1.AST_NODE_TYPES.TSMethodSignature, | ||
utils_1.AST_NODE_TYPES.ArrowFunctionExpression, // const x = (...args: any[]) => {}; | ||
utils_1.AST_NODE_TYPES.FunctionDeclaration, // function f(...args: any[]) {} | ||
utils_1.AST_NODE_TYPES.FunctionExpression, // const x = function(...args: any[]) {}; | ||
utils_1.AST_NODE_TYPES.TSEmptyBodyFunctionExpression, // declare class A { f(...args: any[]): unknown; } | ||
utils_1.AST_NODE_TYPES.TSFunctionType, // type T = (...args: any[]) => unknown; | ||
utils_1.AST_NODE_TYPES.TSConstructorType, // type T = new (...args: any[]) => unknown | ||
utils_1.AST_NODE_TYPES.TSCallSignatureDeclaration, // type T = {(...args: any[]): unknown}; | ||
utils_1.AST_NODE_TYPES.TSConstructSignatureDeclaration, // type T = {new (...args: any[]): unknown}; | ||
utils_1.AST_NODE_TYPES.TSMethodSignature, // type T = {f(...args: any[]): unknown}; | ||
utils_1.AST_NODE_TYPES.TSDeclareFunction, // declare function _8(...args: any[]): unknown; | ||
@@ -93,3 +93,2 @@ ].includes(node.type); | ||
return (node.type === utils_1.AST_NODE_TYPES.TSTypeReference && | ||
node.typeName !== undefined && | ||
node.typeName.type === utils_1.AST_NODE_TYPES.Identifier && | ||
@@ -115,3 +114,3 @@ ['Array', 'ReadonlyArray'].includes(node.typeName.name)); | ||
function isGreatGrandparentRestElement(node) { | ||
return (node?.parent?.parent?.parent != null && | ||
return (node.parent?.parent?.parent != null && | ||
isNodeRestElementInFunction(node.parent.parent.parent)); | ||
@@ -118,0 +117,0 @@ } |
@@ -6,2 +6,3 @@ "use strict"; | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const util_1 = require("../util"); | ||
@@ -25,3 +26,3 @@ const getESLintCoreRule_1 = require("../util/getESLintCoreRule"); | ||
create(context) { | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
const rules = baseRule.create(context); | ||
@@ -252,2 +253,3 @@ function binaryExp(node) { | ||
}; | ||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition | ||
if (rules.ForInStatement && rules.ForOfStatement) { | ||
@@ -254,0 +256,0 @@ overrides.ForInStatement = function (node) { |
@@ -153,6 +153,5 @@ "use strict"; | ||
} | ||
return (node.expression.type === utils_1.AST_NODE_TYPES.CallExpression && | ||
(node.expression.callee.type === | ||
utils_1.AST_NODE_TYPES.ArrowFunctionExpression || | ||
node.expression.callee.type === utils_1.AST_NODE_TYPES.FunctionExpression)); | ||
return (node.expression.callee.type === | ||
utils_1.AST_NODE_TYPES.ArrowFunctionExpression || | ||
node.expression.callee.type === utils_1.AST_NODE_TYPES.FunctionExpression); | ||
} | ||
@@ -159,0 +158,0 @@ function isValidRejectionHandler(rejectionHandler) { |
@@ -27,2 +27,3 @@ "use strict"; | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const tsutils = __importStar(require("ts-api-utils")); | ||
@@ -117,5 +118,3 @@ const ts = __importStar(require("typescript")); | ||
function isReferenceToGlobalFunction(calleeName) { | ||
const ref = context | ||
.getScope() | ||
.references.find(ref => ref.identifier.name === calleeName); | ||
const ref = (0, eslint_utils_1.getScope)(context).references.find(ref => ref.identifier.name === calleeName); | ||
// ensure it's the "global" version | ||
@@ -122,0 +121,0 @@ return !ref?.resolved || ref.resolved.defs.length === 0; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const util_1 = require("../util"); | ||
@@ -20,3 +21,3 @@ exports.default = (0, util_1.createRule)({ | ||
create(context) { | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
return { | ||
@@ -23,0 +24,0 @@ 'ImportDeclaration[importKind!="type"]'(node) { |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const util_1 = require("../util"); | ||
@@ -39,3 +40,3 @@ exports.default = (0, util_1.createRule)({ | ||
create(context, [{ ignoreParameters, ignoreProperties }]) { | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
function isFunctionCall(init, callName) { | ||
@@ -124,3 +125,3 @@ if (init.type === utils_1.AST_NODE_TYPES.ChainExpression) { | ||
function reportInferrableType(node, typeNode, initNode) { | ||
if (!typeNode || !initNode || !typeNode.typeAnnotation) { | ||
if (!typeNode || !initNode) { | ||
return; | ||
@@ -152,9 +153,6 @@ } | ||
function inferrableVariableVisitor(node) { | ||
if (!node.id) { | ||
return; | ||
} | ||
reportInferrableType(node, node.id.typeAnnotation, node.init); | ||
} | ||
function inferrableParameterVisitor(node) { | ||
if (ignoreParameters || !node.params) { | ||
if (ignoreParameters) { | ||
return; | ||
@@ -166,5 +164,3 @@ } | ||
} | ||
if (param.type === utils_1.AST_NODE_TYPES.AssignmentPattern && | ||
param.left && | ||
param.right) { | ||
if (param.type === utils_1.AST_NODE_TYPES.AssignmentPattern) { | ||
reportInferrableType(param, param.left.typeAnnotation, param.right); | ||
@@ -171,0 +167,0 @@ } |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const util_1 = require("../util"); | ||
@@ -74,4 +75,4 @@ exports.default = (0, util_1.createRule)({ | ||
/* istanbul ignore next */ | ||
if (node.parent?.type !== utils_1.AST_NODE_TYPES.TSTypeParameterInstantiation || | ||
node.parent.parent?.type !== utils_1.AST_NODE_TYPES.TSTypeReference) { | ||
if (node.parent.type !== utils_1.AST_NODE_TYPES.TSTypeParameterInstantiation || | ||
node.parent.parent.type !== utils_1.AST_NODE_TYPES.TSTypeReference) { | ||
return; | ||
@@ -81,3 +82,3 @@ } | ||
if (Array.isArray(allowInGenericTypeArguments)) { | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
const fullyQualifiedName = sourceCode | ||
@@ -128,3 +129,3 @@ .getText(node.parent.parent.typeName) | ||
utils_1.AST_NODE_TYPES.TSTypeParameterInstantiation && | ||
member.typeArguments?.params | ||
member.typeArguments.params | ||
.map(param => param.type) | ||
@@ -131,0 +132,0 @@ .includes(utils_1.AST_NODE_TYPES.TSVoidKeyword))); |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const util_1 = require("../util"); | ||
@@ -34,3 +35,3 @@ const getESLintCoreRule_1 = require("../util/getESLintCoreRule"); | ||
} | ||
const references = context.getScope().through; | ||
const references = (0, eslint_utils_1.getScope)(context).through; | ||
const unsafeRefs = references | ||
@@ -165,3 +166,3 @@ .filter(r => !isSafe(loopNode, r)) | ||
return (!upperRef.isWrite() || | ||
(variable?.scope?.variableScope === upperRef.from.variableScope && | ||
(variable?.scope.variableScope === upperRef.from.variableScope && | ||
id.range[0] < border)); | ||
@@ -168,0 +169,0 @@ } |
@@ -87,3 +87,3 @@ "use strict"; | ||
let raw = node.raw; | ||
if (node.parent?.type === utils_1.AST_NODE_TYPES.UnaryExpression && | ||
if (node.parent.type === utils_1.AST_NODE_TYPES.UnaryExpression && | ||
// the base rule only shows the operator for negative numbers | ||
@@ -112,3 +112,3 @@ // https://github.com/eslint/eslint/blob/9dfc8501fb1956c90dc11e6377b4cb38a6bea65d/lib/rules/no-magic-numbers.js#L126 | ||
function getLiteralParent(node) { | ||
if (node.parent?.type === utils_1.AST_NODE_TYPES.UnaryExpression && | ||
if (node.parent.type === utils_1.AST_NODE_TYPES.UnaryExpression && | ||
['-', '+'].includes(node.parent.operator)) { | ||
@@ -115,0 +115,0 @@ return node.parent.parent; |
@@ -27,2 +27,3 @@ "use strict"; | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const tsutils = __importStar(require("ts-api-utils")); | ||
@@ -63,3 +64,3 @@ const ts = __importStar(require("typescript")); | ||
const checker = services.program.getTypeChecker(); | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
return { | ||
@@ -66,0 +67,0 @@ 'UnaryExpression[operator="void"]'(node) { |
@@ -447,3 +447,3 @@ "use strict"; | ||
// 'param: MaybeVoidFunction' | ||
type = (0, util_1.getTypeArguments)(type, checker)[0]; | ||
type = checker.getTypeArguments(type)[0]; | ||
for (let i = index; i < node.arguments.length; i++) { | ||
@@ -456,3 +456,3 @@ checkThenableOrVoidArgument(checker, node, type, i, thenableReturnIndices, voidReturnIndices); | ||
// add the index of the second tuple parameter to 'voidReturnIndices' | ||
const typeArgs = (0, util_1.getTypeArguments)(type, checker); | ||
const typeArgs = checker.getTypeArguments(type); | ||
for (let i = index; i < node.arguments.length && i - index < typeArgs.length; i++) { | ||
@@ -459,0 +459,0 @@ checkThenableOrVoidArgument(checker, node, typeArgs[i - index], i, thenableReturnIndices, voidReturnIndices); |
@@ -28,2 +28,3 @@ "use strict"; | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const tsutils = __importStar(require("ts-api-utils")); | ||
@@ -62,3 +63,3 @@ const ts = __importStar(require("typescript")); | ||
}; | ||
let scope = context.getScope(); | ||
let scope = (0, eslint_utils_1.getScope)(context); | ||
for (const definition of scope.upper?.set.get(name)?.defs ?? []) { | ||
@@ -73,3 +74,3 @@ if (definition.node.type === utils_1.AST_NODE_TYPES.TSEnumDeclaration && | ||
while (scope) { | ||
scope.set.get(name)?.defs?.forEach(definition => { | ||
scope.set.get(name)?.defs.forEach(definition => { | ||
if (definition.type === scope_manager_1.DefinitionType.ImportBinding) { | ||
@@ -183,4 +184,3 @@ found.imports.push(definition.node); | ||
} | ||
if (currentType !== desiredType && | ||
(currentType !== undefined || desiredType === AllowedType.String)) { | ||
if (currentType !== desiredType) { | ||
context.report({ | ||
@@ -187,0 +187,0 @@ messageId: 'mixed', |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const util_1 = require("../util"); | ||
@@ -40,3 +41,3 @@ exports.default = (0, util_1.createRule)({ | ||
create(context, [{ allowDeclarations, allowDefinitionFiles }]) { | ||
const filename = context.getFilename(); | ||
const filename = (0, eslint_utils_1.getFilename)(context); | ||
function isDeclaration(node) { | ||
@@ -43,0 +44,0 @@ if (node.type === utils_1.AST_NODE_TYPES.TSModuleDeclaration && node.declare) { |
@@ -5,2 +5,3 @@ "use strict"; | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const util_1 = require("../util"); | ||
@@ -38,3 +39,3 @@ function hasAssignmentBeforeNode(variable, node) { | ||
if (node.expression.type === utils_1.TSESTree.AST_NODE_TYPES.Identifier) { | ||
const scope = context.getScope(); | ||
const scope = (0, eslint_utils_1.getScope)(context); | ||
const identifier = node.expression; | ||
@@ -46,3 +47,3 @@ const variable = utils_1.ASTUtils.findVariable(scope, identifier.name); | ||
} | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
context.report({ | ||
@@ -49,0 +50,0 @@ node, |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const util_1 = require("../util"); | ||
@@ -22,3 +23,3 @@ exports.default = (0, util_1.createRule)({ | ||
create(context) { | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
return { | ||
@@ -45,3 +46,3 @@ TSNonNullExpression(node) { | ||
} | ||
if (node.parent?.type === utils_1.AST_NODE_TYPES.MemberExpression && | ||
if (node.parent.type === utils_1.AST_NODE_TYPES.MemberExpression && | ||
node.parent.object === node) { | ||
@@ -81,3 +82,3 @@ if (!node.parent.optional) { | ||
} | ||
else if (node.parent?.type === utils_1.AST_NODE_TYPES.CallExpression && | ||
else if (node.parent.type === utils_1.AST_NODE_TYPES.CallExpression && | ||
node.parent.callee === node) { | ||
@@ -84,0 +85,0 @@ if (!node.parent.optional) { |
@@ -5,2 +5,3 @@ "use strict"; | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const util_1 = require("../util"); | ||
@@ -42,3 +43,3 @@ exports.default = (0, util_1.createRule)({ | ||
create(context, [options]) { | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
const CLASS_DECLARATION_MERGE_NODES = new Set([ | ||
@@ -58,3 +59,3 @@ utils_1.AST_NODE_TYPES.TSInterfaceDeclaration, | ||
function* iterateDeclarations(variable) { | ||
if (options?.builtinGlobals && | ||
if (options.builtinGlobals && | ||
'eslintImplicitGlobalSetting' in variable && | ||
@@ -171,3 +172,3 @@ (variable.eslintImplicitGlobalSetting === 'readonly' || | ||
function checkForBlock(node) { | ||
const scope = context.getScope(); | ||
const scope = (0, eslint_utils_1.getScope)(context); | ||
/* | ||
@@ -183,3 +184,3 @@ * In ES5, some node type such as `BlockStatement` doesn't have that scope. | ||
Program() { | ||
const scope = context.getScope(); | ||
const scope = (0, eslint_utils_1.getScope)(context); | ||
findVariablesInScope(scope); | ||
@@ -186,0 +187,0 @@ // Node.js or ES modules has a special scope. |
@@ -146,3 +146,3 @@ "use strict"; | ||
function isNodeInsideReturnType(node) { | ||
return !!(node.parent?.type === utils_1.AST_NODE_TYPES.TSTypeAnnotation && | ||
return !!(node.parent.type === utils_1.AST_NODE_TYPES.TSTypeAnnotation && | ||
((0, util_1.isFunctionType)(node.parent.parent) || (0, util_1.isFunction)(node.parent.parent))); | ||
@@ -149,0 +149,0 @@ } |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const util_1 = require("../util"); | ||
@@ -21,3 +22,3 @@ exports.default = (0, util_1.createRule)({ | ||
'CallExpression[callee.name="require"]'(node) { | ||
const variable = utils_1.ASTUtils.findVariable(context.getScope(), 'require'); | ||
const variable = utils_1.ASTUtils.findVariable((0, eslint_utils_1.getScope)(context), 'require'); | ||
// ignore non-global require usage as it's something user-land custom instead | ||
@@ -24,0 +25,0 @@ // of the commonjs standard |
@@ -197,2 +197,3 @@ "use strict"; | ||
assertions: [], | ||
attributes: [], | ||
specifiers: [ | ||
@@ -199,0 +200,0 @@ { |
@@ -5,2 +5,3 @@ "use strict"; | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const util_1 = require("../util"); | ||
@@ -94,3 +95,3 @@ const allowedFunctionVariableDefTypes = new Set([ | ||
} | ||
const [firstDefinition] = shadowed.defs; | ||
const firstDefinition = shadowed.defs.at(0); | ||
const isShadowedValue = !('isValueVariable' in shadowed) || | ||
@@ -127,17 +128,16 @@ !firstDefinition || | ||
const typeParameter = variable.identifiers[0].parent; | ||
if (typeParameter?.type !== utils_1.AST_NODE_TYPES.TSTypeParameter) { | ||
if (typeParameter.type !== utils_1.AST_NODE_TYPES.TSTypeParameter) { | ||
return false; | ||
} | ||
const typeParameterDecl = typeParameter.parent; | ||
if (typeParameterDecl?.type !== utils_1.AST_NODE_TYPES.TSTypeParameterDeclaration) { | ||
if (typeParameterDecl.type !== utils_1.AST_NODE_TYPES.TSTypeParameterDeclaration) { | ||
return false; | ||
} | ||
const functionExpr = typeParameterDecl.parent; | ||
if (!functionExpr || | ||
(functionExpr.type !== utils_1.AST_NODE_TYPES.FunctionExpression && | ||
functionExpr.type !== utils_1.AST_NODE_TYPES.TSEmptyBodyFunctionExpression)) { | ||
if (functionExpr.type !== utils_1.AST_NODE_TYPES.FunctionExpression && | ||
functionExpr.type !== utils_1.AST_NODE_TYPES.TSEmptyBodyFunctionExpression) { | ||
return false; | ||
} | ||
const methodDefinition = functionExpr.parent; | ||
if (methodDefinition?.type !== utils_1.AST_NODE_TYPES.MethodDefinition) { | ||
if (methodDefinition.type !== utils_1.AST_NODE_TYPES.MethodDefinition) { | ||
return false; | ||
@@ -159,12 +159,12 @@ } | ||
const typeParameter = variable.identifiers[0].parent; | ||
if (typeParameter?.type !== utils_1.AST_NODE_TYPES.TSTypeParameter) { | ||
if (typeParameter.type !== utils_1.AST_NODE_TYPES.TSTypeParameter) { | ||
return false; | ||
} | ||
const typeParameterDecl = typeParameter.parent; | ||
if (typeParameterDecl?.type !== utils_1.AST_NODE_TYPES.TSTypeParameterDeclaration) { | ||
if (typeParameterDecl.type !== utils_1.AST_NODE_TYPES.TSTypeParameterDeclaration) { | ||
return false; | ||
} | ||
const classDecl = typeParameterDecl.parent; | ||
return (classDecl?.type === utils_1.AST_NODE_TYPES.ClassDeclaration || | ||
classDecl?.type === utils_1.AST_NODE_TYPES.ClassExpression); | ||
return (classDecl.type === utils_1.AST_NODE_TYPES.ClassDeclaration || | ||
classDecl.type === utils_1.AST_NODE_TYPES.ClassExpression); | ||
} | ||
@@ -179,3 +179,2 @@ function isGenericOfAStaticMethodShadow(variable, shadowed) { | ||
return (scope.type === scope_manager_1.ScopeType.tsModule && | ||
scope.block.type === utils_1.AST_NODE_TYPES.TSModuleDeclaration && | ||
scope.block.id.type === utils_1.AST_NODE_TYPES.Literal && | ||
@@ -191,3 +190,3 @@ scope.block.id.value === name); | ||
secondDefinition.node.type === utils_1.AST_NODE_TYPES.TSInterfaceDeclaration && | ||
secondDefinition.node.parent?.type === | ||
secondDefinition.node.parent.type === | ||
utils_1.AST_NODE_TYPES.ExportNamedDeclaration); | ||
@@ -270,3 +269,3 @@ } | ||
function isInitPatternNode(variable, shadowedVariable) { | ||
const outerDef = shadowedVariable.defs[0]; | ||
const outerDef = shadowedVariable.defs.at(0); | ||
if (!outerDef) { | ||
@@ -295,4 +294,4 @@ return false; | ||
} | ||
if ((node.parent?.parent?.type === utils_1.AST_NODE_TYPES.ForInStatement || | ||
node.parent?.parent?.type === utils_1.AST_NODE_TYPES.ForOfStatement) && | ||
if ((node.parent.parent?.type === utils_1.AST_NODE_TYPES.ForInStatement || | ||
node.parent.parent?.type === utils_1.AST_NODE_TYPES.ForOfStatement) && | ||
isInRange(node.parent.parent.right, location)) { | ||
@@ -335,6 +334,6 @@ return true; | ||
const outerScope = scopeVar.scope; | ||
const outerDef = scopeVar.defs[0]; | ||
const outerDef = scopeVar.defs.at(0); | ||
const outer = outerDef?.parent?.range; | ||
const innerScope = variable.scope; | ||
const innerDef = variable.defs[0]; | ||
const innerDef = variable.defs.at(0); | ||
const inner = innerDef?.name.range; | ||
@@ -356,3 +355,3 @@ return !!(outer && | ||
function getNameRange(variable) { | ||
const def = variable.defs[0]; | ||
const def = variable.defs.at(0); | ||
return def?.name.range; | ||
@@ -367,3 +366,3 @@ } | ||
function isInTdz(variable, scopeVar) { | ||
const outerDef = scopeVar.defs[0]; | ||
const outerDef = scopeVar.defs.at(0); | ||
const inner = getNameRange(variable); | ||
@@ -385,3 +384,3 @@ const outer = getNameRange(scopeVar); | ||
function getDeclaredLocation(variable) { | ||
const identifier = variable.identifiers[0]; | ||
const identifier = variable.identifiers.at(0); | ||
if (identifier) { | ||
@@ -484,3 +483,3 @@ return { | ||
'Program:exit'() { | ||
const globalScope = context.getScope(); | ||
const globalScope = (0, eslint_utils_1.getScope)(context); | ||
const stack = globalScope.childScopes.slice(); | ||
@@ -487,0 +486,0 @@ while (stack.length) { |
@@ -27,2 +27,3 @@ "use strict"; | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const tsutils = __importStar(require("ts-api-utils")); | ||
@@ -73,3 +74,3 @@ const ts = __importStar(require("typescript")); | ||
const services = (0, util_1.getParserServices)(context); | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
function getBooleanComparison(node) { | ||
@@ -173,3 +174,3 @@ const comparison = deconstructComparison(node); | ||
// 3. negated - is expression negated | ||
const isUnaryNegation = node.parent != null && nodeIsUnaryNegation(node.parent); | ||
const isUnaryNegation = nodeIsUnaryNegation(node.parent); | ||
const shouldNegate = comparison.negated !== comparison.literalBooleanInComparison; | ||
@@ -176,0 +177,0 @@ const mutatedNode = isUnaryNegation ? node.parent : node; |
@@ -27,2 +27,3 @@ "use strict"; | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const tsutils = __importStar(require("ts-api-utils")); | ||
@@ -112,3 +113,3 @@ const ts = __importStar(require("typescript")); | ||
const checker = services.program.getTypeChecker(); | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
const compilerOptions = services.program.getCompilerOptions(); | ||
@@ -335,5 +336,4 @@ const isStrictNullChecks = tsutils.isStrictCompilerOptionEnabled(compilerOptions, 'strictNullChecks'); | ||
// Inline defined functions | ||
if ((callback.type === utils_1.AST_NODE_TYPES.ArrowFunctionExpression || | ||
callback.type === utils_1.AST_NODE_TYPES.FunctionExpression) && | ||
callback.body) { | ||
if (callback.type === utils_1.AST_NODE_TYPES.ArrowFunctionExpression || | ||
callback.type === utils_1.AST_NODE_TYPES.FunctionExpression) { | ||
// Two special cases, where we can directly check the node that's returned: | ||
@@ -411,6 +411,5 @@ // () => something | ||
const typeName = (0, util_1.getTypeName)(checker, propertyType); | ||
return !!((typeName === 'string' && | ||
checker.getIndexInfoOfType(objType, ts.IndexKind.String)) || | ||
(typeName === 'number' && | ||
checker.getIndexInfoOfType(objType, ts.IndexKind.Number))); | ||
return !!checker | ||
.getIndexInfosOfType(objType) | ||
.find(info => (0, util_1.getTypeName)(checker, info.keyType) === typeName); | ||
} | ||
@@ -417,0 +416,0 @@ // Checks whether a member expression is nullable or not regardless of it's previous node. |
@@ -27,2 +27,3 @@ "use strict"; | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const tsutils = __importStar(require("ts-api-utils")); | ||
@@ -52,3 +53,3 @@ const ts = __importStar(require("typescript")); | ||
const checker = services.program.getTypeChecker(); | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
function tryGetAliasedSymbol(symbol, checker) { | ||
@@ -126,3 +127,5 @@ return tsutils.isSymbolFlagSet(symbol, ts.SymbolFlags.Alias) | ||
return { | ||
TSModuleDeclaration: enterDeclaration, | ||
'TSModuleDeclaration > TSModuleBlock'(node) { | ||
enterDeclaration(node.parent); | ||
}, | ||
TSEnumDeclaration: enterDeclaration, | ||
@@ -129,0 +132,0 @@ 'ExportNamedDeclaration[declaration.type="TSModuleDeclaration"]': enterDeclaration, |
@@ -52,3 +52,3 @@ "use strict"; | ||
type: type.target, | ||
typeArguments: (0, util_1.getTypeArguments)(type, checker), | ||
typeArguments: checker.getTypeArguments(type), | ||
}; | ||
@@ -65,3 +65,3 @@ } | ||
const arg = esParameters.params[i]; | ||
const param = typeParameters[i]; | ||
const param = typeParameters.at(i); | ||
if (!param?.default) { | ||
@@ -68,0 +68,0 @@ return; |
@@ -27,2 +27,3 @@ "use strict"; | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const tsutils = __importStar(require("ts-api-utils")); | ||
@@ -63,3 +64,3 @@ const ts = __importStar(require("typescript")); | ||
create(context, [options]) { | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
const services = (0, util_1.getParserServices)(context); | ||
@@ -135,3 +136,3 @@ const checker = services.program.getTypeChecker(); | ||
TSNonNullExpression(node) { | ||
if (node.parent?.type === utils_1.AST_NODE_TYPES.AssignmentExpression && | ||
if (node.parent.type === utils_1.AST_NODE_TYPES.AssignmentExpression && | ||
node.parent.operator === '=') { | ||
@@ -138,0 +139,0 @@ if (node.parent.left === node) { |
@@ -27,2 +27,3 @@ "use strict"; | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const path_1 = require("path"); | ||
@@ -66,4 +67,4 @@ const ts = __importStar(require("typescript")); | ||
} | ||
const requiresGenericDeclarationDisambiguation = checkRequiresGenericDeclarationDisambiguation(context.getFilename()); | ||
const source = context.getSourceCode(); | ||
const requiresGenericDeclarationDisambiguation = checkRequiresGenericDeclarationDisambiguation((0, eslint_utils_1.getFilename)(context)); | ||
const source = (0, eslint_utils_1.getSourceCode)(context); | ||
const checkNode = (node, inArrowFunction) => { | ||
@@ -70,0 +71,0 @@ const constraint = unnecessaryConstraints.get(node.constraint.type); |
@@ -46,3 +46,3 @@ "use strict"; | ||
restType = { | ||
type: (0, util_1.getTypeArguments)(type, checker)[0], | ||
type: checker.getTypeArguments(type)[0], | ||
kind: 0 /* RestTypeKind.Array */, | ||
@@ -54,3 +54,3 @@ index: i, | ||
restType = { | ||
typeArguments: (0, util_1.getTypeArguments)(type, checker), | ||
typeArguments: checker.getTypeArguments(type), | ||
kind: 1 /* RestTypeKind.Tuple */, | ||
@@ -170,3 +170,3 @@ index: i, | ||
// foo(...[tuple1, tuple2]) | ||
const spreadTypeArguments = (0, util_1.getTypeArguments)(spreadArgType, checker); | ||
const spreadTypeArguments = checker.getTypeArguments(spreadArgType); | ||
for (const tupleType of spreadTypeArguments) { | ||
@@ -173,0 +173,0 @@ const parameterType = signature.getNextParameterType(); |
@@ -80,3 +80,3 @@ "use strict"; | ||
} | ||
const tupleElements = (0, util_1.getTypeArguments)(senderType, checker); | ||
const tupleElements = checker.getTypeArguments(senderType); | ||
// tuple with any | ||
@@ -83,0 +83,0 @@ // const [x] = [1 as any]; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const util_1 = require("../util"); | ||
@@ -42,3 +43,3 @@ exports.default = (0, util_1.createRule)({ | ||
// but we want the outer scope within which merged variables will sit | ||
const currentScope = context.getScope().upper; | ||
const currentScope = (0, eslint_utils_1.getScope)(context).upper; | ||
if (currentScope == null) { | ||
@@ -51,3 +52,3 @@ return; | ||
TSInterfaceDeclaration(node) { | ||
checkUnsafeDeclaration(context.getScope(), node.id, utils_1.AST_NODE_TYPES.ClassDeclaration); | ||
checkUnsafeDeclaration((0, eslint_utils_1.getScope)(context), node.id, utils_1.AST_NODE_TYPES.ClassDeclaration); | ||
}, | ||
@@ -54,0 +55,0 @@ }; |
@@ -61,3 +61,4 @@ "use strict"; | ||
messages: { | ||
mismatched: 'The two values in this comparison do not have a shared enum type.', | ||
mismatchedCase: 'The case statement does not have a shared enum type with the switch predicate.', | ||
mismatchedCondition: 'The two values in this comparison do not have a shared enum type.', | ||
replaceValueWithEnum: 'Replace with an enum value comparison.', | ||
@@ -71,43 +72,46 @@ }, | ||
const typeChecker = parserServices.program.getTypeChecker(); | ||
function isMismatchedComparison(leftType, rightType) { | ||
// Allow comparisons that don't have anything to do with enums: | ||
// | ||
// ```ts | ||
// 1 === 2; | ||
// ``` | ||
const leftEnumTypes = (0, shared_1.getEnumTypes)(typeChecker, leftType); | ||
const rightEnumTypes = new Set((0, shared_1.getEnumTypes)(typeChecker, rightType)); | ||
if (leftEnumTypes.length === 0 && rightEnumTypes.size === 0) { | ||
return false; | ||
} | ||
// Allow comparisons that share an enum type: | ||
// | ||
// ```ts | ||
// Fruit.Apple === Fruit.Banana; | ||
// ``` | ||
for (const leftEnumType of leftEnumTypes) { | ||
if (rightEnumTypes.has(leftEnumType)) { | ||
return false; | ||
} | ||
} | ||
const leftTypeParts = tsutils.unionTypeParts(leftType); | ||
const rightTypeParts = tsutils.unionTypeParts(rightType); | ||
// If a type exists in both sides, we consider this comparison safe: | ||
// | ||
// ```ts | ||
// declare const fruit: Fruit.Apple | 0; | ||
// fruit === 0; | ||
// ``` | ||
for (const leftTypePart of leftTypeParts) { | ||
if (rightTypeParts.includes(leftTypePart)) { | ||
return false; | ||
} | ||
} | ||
return (typeViolates(leftTypeParts, rightType) || | ||
typeViolates(rightTypeParts, leftType)); | ||
} | ||
return { | ||
'BinaryExpression[operator=/^[<>!=]?={0,2}$/]'(node) { | ||
const left = parserServices.getTypeAtLocation(node.left); | ||
const right = parserServices.getTypeAtLocation(node.right); | ||
// Allow comparisons that don't have anything to do with enums: | ||
// | ||
// ```ts | ||
// 1 === 2; | ||
// ``` | ||
const leftEnumTypes = (0, shared_1.getEnumTypes)(typeChecker, left); | ||
const rightEnumTypes = new Set((0, shared_1.getEnumTypes)(typeChecker, right)); | ||
if (leftEnumTypes.length === 0 && rightEnumTypes.size === 0) { | ||
return; | ||
} | ||
// Allow comparisons that share an enum type: | ||
// | ||
// ```ts | ||
// Fruit.Apple === Fruit.Banana; | ||
// ``` | ||
for (const leftEnumType of leftEnumTypes) { | ||
if (rightEnumTypes.has(leftEnumType)) { | ||
return; | ||
} | ||
} | ||
const leftTypeParts = tsutils.unionTypeParts(left); | ||
const rightTypeParts = tsutils.unionTypeParts(right); | ||
// If a type exists in both sides, we consider this comparison safe: | ||
// | ||
// ```ts | ||
// declare const fruit: Fruit.Apple | 0; | ||
// fruit === 0; | ||
// ``` | ||
for (const leftTypePart of leftTypeParts) { | ||
if (rightTypeParts.includes(leftTypePart)) { | ||
return; | ||
} | ||
} | ||
if (typeViolates(leftTypeParts, right) || | ||
typeViolates(rightTypeParts, left)) { | ||
const leftType = parserServices.getTypeAtLocation(node.left); | ||
const rightType = parserServices.getTypeAtLocation(node.right); | ||
if (isMismatchedComparison(leftType, rightType)) { | ||
context.report({ | ||
messageId: 'mismatched', | ||
messageId: 'mismatchedCondition', | ||
node, | ||
@@ -123,3 +127,3 @@ suggest: [ | ||
// ``` | ||
const leftEnumKey = (0, shared_1.getEnumKeyForLiteral)((0, shared_1.getEnumLiterals)(left), (0, util_1.getStaticValue)(node.right)?.value); | ||
const leftEnumKey = (0, shared_1.getEnumKeyForLiteral)((0, shared_1.getEnumLiterals)(leftType), (0, util_1.getStaticValue)(node.right)?.value); | ||
if (leftEnumKey) { | ||
@@ -134,3 +138,3 @@ return fixer.replaceText(node.right, leftEnumKey); | ||
// ``` | ||
const rightEnumKey = (0, shared_1.getEnumKeyForLiteral)((0, shared_1.getEnumLiterals)(right), (0, util_1.getStaticValue)(node.left)?.value); | ||
const rightEnumKey = (0, shared_1.getEnumKeyForLiteral)((0, shared_1.getEnumLiterals)(rightType), (0, util_1.getStaticValue)(node.left)?.value); | ||
if (rightEnumKey) { | ||
@@ -146,2 +150,21 @@ return fixer.replaceText(node.left, rightEnumKey); | ||
}, | ||
SwitchCase(node) { | ||
// Ignore `default` cases. | ||
if (node.test == null) { | ||
return; | ||
} | ||
const { parent } = node; | ||
/** | ||
* @see https://github.com/typescript-eslint/typescript-eslint/issues/6225 | ||
*/ | ||
const switchStatement = parent; | ||
const leftType = parserServices.getTypeAtLocation(switchStatement.discriminant); | ||
const rightType = parserServices.getTypeAtLocation(node.test); | ||
if (isMismatchedComparison(leftType, rightType)) { | ||
context.report({ | ||
messageId: 'mismatchedCase', | ||
node, | ||
}); | ||
} | ||
}, | ||
}; | ||
@@ -148,0 +171,0 @@ }, |
@@ -27,2 +27,3 @@ "use strict"; | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const tsutils = __importStar(require("ts-api-utils")); | ||
@@ -54,3 +55,3 @@ const util_1 = require("../util"); | ||
const isNoImplicitThis = tsutils.isStrictCompilerOptionEnabled(compilerOptions, 'noImplicitThis'); | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
const stateCache = new Map(); | ||
@@ -57,0 +58,0 @@ function checkMemberExpression(node) { |
@@ -5,2 +5,3 @@ "use strict"; | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const util_1 = require("../util"); | ||
@@ -65,4 +66,4 @@ exports.default = (0, util_1.createRule)({ | ||
create(context, [firstOption]) { | ||
const filename = context.getFilename(); | ||
const sourceCode = context.getSourceCode(); | ||
const filename = (0, eslint_utils_1.getFilename)(context); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
const MODULE_DECL_CACHE = new Map(); | ||
@@ -76,26 +77,23 @@ const options = (() => { | ||
}; | ||
if (firstOption) { | ||
if (typeof firstOption === 'string') { | ||
options.vars = firstOption; | ||
if (typeof firstOption === 'string') { | ||
options.vars = firstOption; | ||
} | ||
else { | ||
options.vars = firstOption.vars ?? options.vars; | ||
options.args = firstOption.args ?? options.args; | ||
options.ignoreRestSiblings = | ||
firstOption.ignoreRestSiblings ?? options.ignoreRestSiblings; | ||
options.caughtErrors = firstOption.caughtErrors ?? options.caughtErrors; | ||
if (firstOption.varsIgnorePattern) { | ||
options.varsIgnorePattern = new RegExp(firstOption.varsIgnorePattern, 'u'); | ||
} | ||
else { | ||
options.vars = firstOption.vars ?? options.vars; | ||
options.args = firstOption.args ?? options.args; | ||
options.ignoreRestSiblings = | ||
firstOption.ignoreRestSiblings ?? options.ignoreRestSiblings; | ||
options.caughtErrors = | ||
firstOption.caughtErrors ?? options.caughtErrors; | ||
if (firstOption.varsIgnorePattern) { | ||
options.varsIgnorePattern = new RegExp(firstOption.varsIgnorePattern, 'u'); | ||
} | ||
if (firstOption.argsIgnorePattern) { | ||
options.argsIgnorePattern = new RegExp(firstOption.argsIgnorePattern, 'u'); | ||
} | ||
if (firstOption.caughtErrorsIgnorePattern) { | ||
options.caughtErrorsIgnorePattern = new RegExp(firstOption.caughtErrorsIgnorePattern, 'u'); | ||
} | ||
if (firstOption.destructuredArrayIgnorePattern) { | ||
options.destructuredArrayIgnorePattern = new RegExp(firstOption.destructuredArrayIgnorePattern, 'u'); | ||
} | ||
if (firstOption.argsIgnorePattern) { | ||
options.argsIgnorePattern = new RegExp(firstOption.argsIgnorePattern, 'u'); | ||
} | ||
if (firstOption.caughtErrorsIgnorePattern) { | ||
options.caughtErrorsIgnorePattern = new RegExp(firstOption.caughtErrorsIgnorePattern, 'u'); | ||
} | ||
if (firstOption.destructuredArrayIgnorePattern) { | ||
options.destructuredArrayIgnorePattern = new RegExp(firstOption.destructuredArrayIgnorePattern, 'u'); | ||
} | ||
} | ||
@@ -112,3 +110,3 @@ return options; | ||
return (node.type === utils_1.AST_NODE_TYPES.Property && | ||
node.parent?.type === utils_1.AST_NODE_TYPES.ObjectPattern && | ||
node.parent.type === utils_1.AST_NODE_TYPES.ObjectPattern && | ||
node.parent.properties[node.parent.properties.length - 1].type === | ||
@@ -137,3 +135,3 @@ utils_1.AST_NODE_TYPES.RestElement); | ||
const def = variable.defs[0]; | ||
const params = context.getDeclaredVariables(def.node); | ||
const params = (0, eslint_utils_1.getDeclaredVariables)(context, def.node); | ||
const posteriorParams = params.slice(params.indexOf(variable) + 1); | ||
@@ -157,5 +155,5 @@ // If any used parameters occur after this parameter, do not report. | ||
} | ||
const refUsedInArrayPatterns = variable.references.some(ref => ref.identifier.parent?.type === utils_1.AST_NODE_TYPES.ArrayPattern); | ||
const refUsedInArrayPatterns = variable.references.some(ref => ref.identifier.parent.type === utils_1.AST_NODE_TYPES.ArrayPattern); | ||
// skip elements of array destructuring patterns | ||
if ((def.name.parent?.type === utils_1.AST_NODE_TYPES.ArrayPattern || | ||
if ((def.name.parent.type === utils_1.AST_NODE_TYPES.ArrayPattern || | ||
refUsedInArrayPatterns) && | ||
@@ -225,3 +223,3 @@ 'name' in def.name && | ||
if (node.id.type === utils_1.AST_NODE_TYPES.Identifier) { | ||
let scope = context.getScope(); | ||
let scope = (0, eslint_utils_1.getScope)(context); | ||
if (scope.upper) { | ||
@@ -242,3 +240,3 @@ scope = scope.upper; | ||
[ambientDeclarationSelector('TSModuleDeclaration[declare = true] > TSModuleBlock', false)](node) { | ||
const moduleDecl = (0, util_1.nullThrows)(node.parent?.parent, util_1.NullThrowsReasons.MissingParent); | ||
const moduleDecl = (0, util_1.nullThrows)(node.parent.parent, util_1.NullThrowsReasons.MissingParent); | ||
// declared ambient modules with an `export =` statement will only export that one thing | ||
@@ -261,3 +259,3 @@ // all other statements are not automatically exported in this case | ||
function getDefinedMessageData(unusedVar) { | ||
const defType = unusedVar?.defs[0]?.type; | ||
const defType = unusedVar.defs[0]?.type; | ||
let type; | ||
@@ -296,6 +294,6 @@ let pattern; | ||
function getAssignedMessageData(unusedVar) { | ||
const def = unusedVar.defs[0]; | ||
const def = unusedVar.defs.at(0); | ||
let additional = ''; | ||
if (options.destructuredArrayIgnorePattern && | ||
def?.name.parent?.type === utils_1.AST_NODE_TYPES.ArrayPattern) { | ||
def?.name.parent.type === utils_1.AST_NODE_TYPES.ArrayPattern) { | ||
additional = `. Allowed unused elements of array destructuring patterns must match ${options.destructuredArrayIgnorePattern.toString()}`; | ||
@@ -347,3 +345,3 @@ } | ||
} | ||
if (node.body && node.body.type === utils_1.AST_NODE_TYPES.TSModuleBlock) { | ||
if (node.body) { | ||
for (const statement of node.body.body) { | ||
@@ -398,3 +396,3 @@ if (statement.type === utils_1.AST_NODE_TYPES.TSExportAssignment) { | ||
} | ||
let scope = context.getScope(); | ||
let scope = (0, eslint_utils_1.getScope)(context); | ||
const shouldUseUpperScope = [ | ||
@@ -401,0 +399,0 @@ utils_1.AST_NODE_TYPES.TSModuleDeclaration, |
@@ -5,2 +5,3 @@ "use strict"; | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const util_1 = require("../util"); | ||
@@ -79,3 +80,3 @@ const SENTINEL_TYPE = /^(?:(?:Function|Class)(?:Declaration|Expression)|ArrowFunctionExpression|CatchClause|ImportDeclaration|ExportNamedDeclaration)$/; | ||
const { identifier } = reference; | ||
return (identifier.parent?.type === utils_1.AST_NODE_TYPES.ExportSpecifier && | ||
return (identifier.parent.type === utils_1.AST_NODE_TYPES.ExportSpecifier && | ||
identifier.parent.local === identifier); | ||
@@ -116,6 +117,3 @@ } | ||
function isClassRefInClassDecorator(variable, reference) { | ||
if (variable.defs[0].type !== scope_manager_1.DefinitionType.ClassName) { | ||
return false; | ||
} | ||
if (!variable.defs[0].node.decorators || | ||
if (variable.defs[0].type !== scope_manager_1.DefinitionType.ClassName || | ||
variable.defs[0].node.decorators.length === 0) { | ||
@@ -153,5 +151,4 @@ return false; | ||
} | ||
if (node.parent?.parent && | ||
(node.parent.parent.type === utils_1.AST_NODE_TYPES.ForInStatement || | ||
node.parent.parent.type === utils_1.AST_NODE_TYPES.ForOfStatement) && | ||
if ((node.parent.parent?.type === utils_1.AST_NODE_TYPES.ForInStatement || | ||
node.parent.parent?.type === utils_1.AST_NODE_TYPES.ForOfStatement) && | ||
isInRange(node.parent.parent.right, location)) { | ||
@@ -299,3 +296,3 @@ return true; | ||
Program() { | ||
findVariablesInScope(context.getScope()); | ||
findVariablesInScope((0, eslint_utils_1.getScope)(context)); | ||
}, | ||
@@ -302,0 +299,0 @@ }; |
@@ -50,4 +50,3 @@ "use strict"; | ||
MethodDefinition(node) { | ||
if (node.value?.type === utils_1.AST_NODE_TYPES.FunctionExpression && | ||
node.value.body && | ||
if (node.value.type === utils_1.AST_NODE_TYPES.FunctionExpression && | ||
checkAccessibility(node) && | ||
@@ -54,0 +53,0 @@ checkParams(node)) { |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const util_1 = require("../util"); | ||
@@ -38,3 +39,3 @@ function isEmptyExport(node) { | ||
// https://github.com/typescript-eslint/typescript-eslint/issues/4975 | ||
if ((0, util_1.isDefinitionFile)(context.getFilename())) { | ||
if ((0, util_1.isDefinitionFile)((0, eslint_utils_1.getFilename)(context))) { | ||
return {}; | ||
@@ -41,0 +42,0 @@ } |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const util_1 = require("../util"); | ||
@@ -22,15 +23,14 @@ exports.default = (0, util_1.createRule)({ | ||
'CallExpression[callee.name="require"]'(node) { | ||
const parent = node.parent?.type === utils_1.AST_NODE_TYPES.ChainExpression | ||
const parent = node.parent.type === utils_1.AST_NODE_TYPES.ChainExpression | ||
? node.parent.parent | ||
: node.parent; | ||
if (parent && | ||
[ | ||
utils_1.AST_NODE_TYPES.CallExpression, | ||
utils_1.AST_NODE_TYPES.MemberExpression, | ||
utils_1.AST_NODE_TYPES.NewExpression, | ||
utils_1.AST_NODE_TYPES.TSAsExpression, | ||
utils_1.AST_NODE_TYPES.TSTypeAssertion, | ||
utils_1.AST_NODE_TYPES.VariableDeclarator, | ||
].includes(parent.type)) { | ||
const variable = utils_1.ASTUtils.findVariable(context.getScope(), 'require'); | ||
if ([ | ||
utils_1.AST_NODE_TYPES.CallExpression, | ||
utils_1.AST_NODE_TYPES.MemberExpression, | ||
utils_1.AST_NODE_TYPES.NewExpression, | ||
utils_1.AST_NODE_TYPES.TSAsExpression, | ||
utils_1.AST_NODE_TYPES.TSTypeAssertion, | ||
utils_1.AST_NODE_TYPES.VariableDeclarator, | ||
].includes(parent.type)) { | ||
const variable = utils_1.ASTUtils.findVariable((0, eslint_utils_1.getScope)(context), 'require'); | ||
if (!variable?.identifiers.length) { | ||
@@ -37,0 +37,0 @@ context.report({ |
@@ -27,2 +27,3 @@ "use strict"; | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const tsutils = __importStar(require("ts-api-utils")); | ||
@@ -49,3 +50,3 @@ const ts = __importStar(require("typescript")); | ||
const services = (0, util_1.getParserServices)(context); | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
const getTypesIfNotLoose = (node) => { | ||
@@ -52,0 +53,0 @@ const type = services.getTypeAtLocation(node); |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const util_1 = require("../util"); | ||
@@ -22,3 +23,3 @@ const getESLintCoreRule_1 = require("../util/getESLintCoreRule"); | ||
const spaced = firstOption === 'always'; | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
/** | ||
@@ -48,5 +49,5 @@ * Determines whether an option is set, relative to the spacing option. | ||
function reportNoBeginningSpace(node, token) { | ||
const nextToken = context | ||
.getSourceCode() | ||
.getTokenAfter(token, { includeComments: true }); | ||
const nextToken = (0, eslint_utils_1.getSourceCode)(context).getTokenAfter(token, { | ||
includeComments: true, | ||
}); | ||
context.report({ | ||
@@ -70,5 +71,5 @@ node, | ||
function reportNoEndingSpace(node, token) { | ||
const previousToken = context | ||
.getSourceCode() | ||
.getTokenBefore(token, { includeComments: true }); | ||
const previousToken = (0, eslint_utils_1.getSourceCode)(context).getTokenBefore(token, { | ||
includeComments: true, | ||
}); | ||
context.report({ | ||
@@ -75,0 +76,0 @@ node, |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const util_1 = require("../util"); | ||
@@ -71,5 +72,3 @@ const LT = `[${Array.from(new Set(['\r\n', '\r', '\n', '\u2028', '\u2029'])).join('')}]`; | ||
function skipChainExpression(node) { | ||
return node && node.type === utils_1.AST_NODE_TYPES.ChainExpression | ||
? node.expression | ||
: node; | ||
return node.type === utils_1.AST_NODE_TYPES.ChainExpression ? node.expression : node; | ||
} | ||
@@ -106,5 +105,5 @@ /** | ||
if (node.type === utils_1.AST_NODE_TYPES.VariableDeclaration) { | ||
const declaration = node.declarations[0]; | ||
const declaration = node.declarations.at(0); | ||
if (declaration?.init) { | ||
let call = declaration?.init; | ||
let call = declaration.init; | ||
while (call.type === utils_1.AST_NODE_TYPES.MemberExpression) { | ||
@@ -159,4 +158,4 @@ call = call.object; | ||
return (node.type === utils_1.AST_NODE_TYPES.ExpressionStatement && | ||
(node.parent?.type === utils_1.AST_NODE_TYPES.Program || | ||
(node.parent?.type === utils_1.AST_NODE_TYPES.BlockStatement && | ||
(node.parent.type === utils_1.AST_NODE_TYPES.Program || | ||
(node.parent.type === utils_1.AST_NODE_TYPES.BlockStatement && | ||
(0, util_1.isFunction)(node.parent.parent))) && | ||
@@ -298,4 +297,3 @@ node.expression.type === utils_1.AST_NODE_TYPES.Literal && | ||
const end = nextToken.range[0]; | ||
const text = context | ||
.getSourceCode() | ||
const text = (0, eslint_utils_1.getSourceCode)(context) | ||
.text.slice(start, end) | ||
@@ -328,3 +326,3 @@ .replace(PADDING_LINE_SEQUENCE, replacerToRemovePaddingLines); | ||
fix(fixer) { | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
let prevToken = getActualLastToken(prevNode, sourceCode); | ||
@@ -500,5 +498,5 @@ const nextToken = sourceCode.getFirstTokenBetween(prevToken, nextNode, { | ||
create(context) { | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
// eslint-disable-next-line no-restricted-syntax -- We need all raw options. | ||
const configureList = context.options || []; | ||
const configureList = context.options; | ||
let scopeInfo = null; | ||
@@ -505,0 +503,0 @@ /** |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const util_1 = require("../util"); | ||
@@ -106,3 +107,3 @@ exports.default = (0, util_1.createRule)({ | ||
} | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
function typeAnnotationsMatch(classProperty, constructorParameter) { | ||
@@ -109,0 +110,0 @@ if (!classProperty.typeAnnotation || |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const util_1 = require("../util"); | ||
@@ -20,3 +21,3 @@ exports.default = (0, util_1.createRule)({ | ||
create(context) { | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
function TSEnumDeclaration(node) { | ||
@@ -23,0 +24,0 @@ const { members } = node; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const util_1 = require("../util"); | ||
@@ -107,3 +108,3 @@ exports.default = (0, util_1.createRule)({ | ||
parent.value === node && | ||
parent.parent?.type === utils_1.AST_NODE_TYPES.ObjectExpression && | ||
parent.parent.type === utils_1.AST_NODE_TYPES.ObjectExpression && | ||
isAssignee(parent.parent)) { | ||
@@ -115,3 +116,3 @@ return true; | ||
function isIndexOnlyUsedWithArray(body, indexVar, arrayExpression) { | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
const arrayText = sourceCode.getText(arrayExpression); | ||
@@ -122,4 +123,3 @@ return indexVar.references.every(reference => { | ||
return (!contains(body, id) || | ||
(node !== undefined && | ||
node.type === utils_1.AST_NODE_TYPES.MemberExpression && | ||
(node.type === utils_1.AST_NODE_TYPES.MemberExpression && | ||
node.object.type !== utils_1.AST_NODE_TYPES.ThisExpression && | ||
@@ -147,3 +147,3 @@ node.property === id && | ||
} | ||
const [indexVar] = context.getDeclaredVariables(node.init); | ||
const [indexVar] = (0, eslint_utils_1.getDeclaredVariables)(context, node.init); | ||
if (isIncrement(node.update, indexName) && | ||
@@ -150,0 +150,0 @@ isIndexOnlyUsedWithArray(node.body, indexVar, arrayExpression)) { |
@@ -5,2 +5,3 @@ "use strict"; | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const util_1 = require("../util"); | ||
@@ -28,3 +29,3 @@ exports.phrases = { | ||
create(context) { | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
/** | ||
@@ -35,3 +36,3 @@ * Checks if there the interface has exactly one supertype that isn't named 'Function' | ||
function hasOneSupertype(node) { | ||
if (!node.extends || node.extends.length === 0) { | ||
if (node.extends.length === 0) { | ||
return false; | ||
@@ -38,0 +39,0 @@ } |
@@ -28,2 +28,3 @@ "use strict"; | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const ts = __importStar(require("typescript")); | ||
@@ -49,3 +50,3 @@ const util_1 = require("../util"); | ||
create(context) { | ||
const globalScope = context.getScope(); | ||
const globalScope = (0, eslint_utils_1.getScope)(context); | ||
const services = (0, util_1.getParserServices)(context); | ||
@@ -142,3 +143,3 @@ const checker = services.program.getTypeChecker(); | ||
const callNode = node.parent; | ||
const compareNode = (callNode.parent?.type === utils_1.AST_NODE_TYPES.ChainExpression | ||
const compareNode = (callNode.parent.type === utils_1.AST_NODE_TYPES.ChainExpression | ||
? callNode.parent.parent | ||
@@ -145,0 +146,0 @@ : callNode.parent); |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const util_1 = require("../util"); | ||
@@ -21,7 +22,7 @@ exports.default = (0, util_1.createRule)({ | ||
create(context) { | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
return { | ||
TSModuleDeclaration(node) { | ||
// Do nothing if the name is a string. | ||
if (!node.id || node.id.type === utils_1.AST_NODE_TYPES.Literal) { | ||
if (node.id.type === utils_1.AST_NODE_TYPES.Literal) { | ||
return; | ||
@@ -28,0 +29,0 @@ } |
@@ -27,2 +27,3 @@ "use strict"; | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const tsutils = __importStar(require("ts-api-utils")); | ||
@@ -102,3 +103,3 @@ const ts = __importStar(require("typescript")); | ||
const compilerOptions = parserServices.program.getCompilerOptions(); | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
const checker = parserServices.program.getTypeChecker(); | ||
@@ -275,3 +276,3 @@ const isStrictNullChecks = tsutils.isStrictCompilerOptionEnabled(compilerOptions, 'strictNullChecks'); | ||
function* fix(fixer) { | ||
if (node.parent && (0, util_1.isLogicalOrOperator)(node.parent)) { | ||
if ((0, util_1.isLogicalOrOperator)(node.parent)) { | ||
// '&&' and '??' operations cannot be mixed without parentheses (e.g. a && b ?? c) | ||
@@ -339,3 +340,3 @@ if (node.left.type === utils_1.AST_NODE_TYPES.LogicalExpression && | ||
seen.add(current); | ||
if (current && current.type === utils_1.AST_NODE_TYPES.LogicalExpression) { | ||
if (current.type === utils_1.AST_NODE_TYPES.LogicalExpression) { | ||
if (current.operator === '&&') { | ||
@@ -342,0 +343,0 @@ return true; |
@@ -403,3 +403,3 @@ "use strict"; | ||
} | ||
else if (comparisonResult === "Equal" /* NodeComparisonResult.Equal */) { | ||
else { | ||
// purposely don't push this case because the node is a no-op and if | ||
@@ -406,0 +406,0 @@ // we consider it then we might report on things like |
@@ -27,2 +27,3 @@ "use strict"; | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const ts = __importStar(require("typescript")); | ||
@@ -101,3 +102,3 @@ const util_1 = require("../util"); | ||
create(context, [options]) { | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
const parserServices = (0, util_1.getParserServices)(context); | ||
@@ -114,3 +115,2 @@ const seenLogicals = new Set(); | ||
if (!isRightNodeAnEmptyObjectLiteral || | ||
!parentNode || | ||
parentNode.type !== utils_1.AST_NODE_TYPES.MemberExpression || | ||
@@ -117,0 +117,0 @@ parentNode.optional) { |
@@ -27,2 +27,3 @@ "use strict"; | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const tsutils = __importStar(require("ts-api-utils")); | ||
@@ -142,3 +143,3 @@ const ts = __importStar(require("typescript")); | ||
const finalizedClassScope = classScopeStack.pop(); | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
for (const violatingNode of finalizedClassScope.finalizeUnmodifiedPrivateNonReadonlys()) { | ||
@@ -145,0 +146,0 @@ const { esNode, nameNode } = getEsNodesFromViolatingNode(violatingNode); |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const util_1 = require("../util"); | ||
@@ -62,5 +63,3 @@ const getMemberExpressionName = (member) => { | ||
if (!callee.parent.typeArguments) { | ||
fixes.push(fixer.insertTextAfter(callee, `<${context | ||
.getSourceCode() | ||
.getText(secondArg.typeAnnotation)}>`)); | ||
fixes.push(fixer.insertTextAfter(callee, `<${(0, eslint_utils_1.getSourceCode)(context).getText(secondArg.typeAnnotation)}>`)); | ||
} | ||
@@ -67,0 +66,0 @@ return fixes; |
@@ -27,2 +27,3 @@ "use strict"; | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const tsutils = __importStar(require("ts-api-utils")); | ||
@@ -53,6 +54,6 @@ const util_1 = require("../util"); | ||
create(context) { | ||
const globalScope = context.getScope(); | ||
const globalScope = (0, eslint_utils_1.getScope)(context); | ||
const services = (0, util_1.getParserServices)(context); | ||
const checker = services.program.getTypeChecker(); | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
/** | ||
@@ -87,5 +88,4 @@ * Check if a given node type is a string. | ||
node.type === utils_1.AST_NODE_TYPES.NewExpression) { | ||
const [, flags] = node.arguments; | ||
return (flags && | ||
flags.type === utils_1.AST_NODE_TYPES.Literal && | ||
const flags = node.arguments.at(1); | ||
return !!(flags?.type === utils_1.AST_NODE_TYPES.Literal && | ||
typeof flags.value === 'string' && | ||
@@ -92,0 +92,0 @@ flags.value.includes('g')); |
@@ -65,6 +65,4 @@ "use strict"; | ||
function isThisSpecifiedInParameters(originalFunc) { | ||
const firstArg = originalFunc.params[0]; | ||
return (firstArg && | ||
firstArg.type === utils_1.AST_NODE_TYPES.Identifier && | ||
firstArg.name === 'this'); | ||
const firstArg = originalFunc.params.at(0); | ||
return !!(firstArg?.type === utils_1.AST_NODE_TYPES.Identifier && firstArg.name === 'this'); | ||
} | ||
@@ -71,0 +69,0 @@ function isFunctionReturningThis(originalFunc, originalClass) { |
@@ -5,2 +5,3 @@ "use strict"; | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const util_1 = require("../util"); | ||
@@ -27,4 +28,4 @@ const EQ_OPERATORS = /^[=!]=/; | ||
create(context) { | ||
const globalScope = context.getScope(); | ||
const sourceCode = context.getSourceCode(); | ||
const globalScope = (0, eslint_utils_1.getScope)(context); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
const services = (0, util_1.getParserServices)(context); | ||
@@ -280,3 +281,3 @@ const checker = services.program.getTypeChecker(); | ||
let indexNode = null; | ||
if (parentNode?.type === utils_1.AST_NODE_TYPES.CallExpression) { | ||
if (parentNode.type === utils_1.AST_NODE_TYPES.CallExpression) { | ||
if (parentNode.arguments.length === 1) { | ||
@@ -283,0 +284,0 @@ indexNode = parentNode.arguments[0]; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const util_1 = require("../util"); | ||
@@ -23,3 +24,3 @@ exports.default = (0, util_1.createRule)({ | ||
const tsIgnoreRegExpMultiLine = /^\s*(?:\/|\*)*\s*@ts-ignore/; | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
function isLineComment(comment) { | ||
@@ -26,0 +27,0 @@ return comment.type === utils_1.AST_TOKEN_TYPES.Line; |
@@ -27,2 +27,3 @@ "use strict"; | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const ts = __importStar(require("typescript")); | ||
@@ -91,3 +92,3 @@ const util_1 = require("../util"); | ||
const checker = services.program.getTypeChecker(); | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
function validateNode(node) { | ||
@@ -94,0 +95,0 @@ const signatures = services.getTypeAtLocation(node).getCallSignatures(); |
@@ -31,3 +31,3 @@ "use strict"; | ||
const parent = node.parent; | ||
switch (parent?.type) { | ||
switch (parent.type) { | ||
case utils_1.AST_NODE_TYPES.TSAbstractMethodDefinition: | ||
@@ -34,0 +34,0 @@ case utils_1.AST_NODE_TYPES.TSMethodSignature: |
@@ -43,3 +43,3 @@ "use strict"; | ||
if (checker.isArrayType(type) || checker.isTupleType(type)) { | ||
const typeArgs = (0, util_1.getTypeArguments)(type, checker); | ||
const typeArgs = checker.getTypeArguments(type); | ||
return typeArgs.every(arg => (0, util_1.getTypeName)(checker, arg) === 'string'); | ||
@@ -46,0 +46,0 @@ } |
@@ -27,2 +27,3 @@ "use strict"; | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const tsutils = __importStar(require("ts-api-utils")); | ||
@@ -49,3 +50,3 @@ const util_1 = require("../util"); | ||
const checker = services.program.getTypeChecker(); | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
let scopeInfo = null; | ||
@@ -135,2 +136,3 @@ /** | ||
AwaitExpression: markAsHasAwait, | ||
'VariableDeclaration[kind = "await using"]': markAsHasAwait, | ||
'ForOfStatement[await = true]': markAsHasAwait, | ||
@@ -142,3 +144,3 @@ 'YieldExpression[delegate = true]': markAsHasDelegateGen, | ||
const expression = services.esTreeNodeToTSNodeMap.get(node); | ||
if (expression && isThenableType(expression)) { | ||
if (isThenableType(expression)) { | ||
markAsHasAwait(); | ||
@@ -161,3 +163,3 @@ } | ||
function isEmptyFunction(node) { | ||
return (node.body?.type === utils_1.AST_NODE_TYPES.BlockStatement && | ||
return (node.body.type === utils_1.AST_NODE_TYPES.BlockStatement && | ||
node.body.body.length === 0); | ||
@@ -164,0 +166,0 @@ } |
@@ -27,2 +27,3 @@ "use strict"; | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const tsutils = __importStar(require("ts-api-utils")); | ||
@@ -59,3 +60,3 @@ const ts = __importStar(require("typescript")); | ||
const checker = services.program.getTypeChecker(); | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
const scopeInfoStack = []; | ||
@@ -257,3 +258,3 @@ function enterFunction(node) { | ||
ReturnStatement(node) { | ||
const scopeInfo = scopeInfoStack[scopeInfoStack.length - 1]; | ||
const scopeInfo = scopeInfoStack.at(-1); | ||
if (!scopeInfo?.hasAsync || !node.argument) { | ||
@@ -260,0 +261,0 @@ return; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const util_1 = require("../util"); | ||
@@ -144,3 +145,3 @@ var Group; | ||
create(context, [{ checkIntersections, checkUnions, groupOrder }]) { | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
const collator = new Intl.Collator('en', { | ||
@@ -180,3 +181,3 @@ sensitivity: 'base', | ||
}; | ||
if (node.parent?.type === utils_1.AST_NODE_TYPES.TSTypeAliasDeclaration) { | ||
if (node.parent.type === utils_1.AST_NODE_TYPES.TSTypeAliasDeclaration) { | ||
messageId = 'notSortedNamed'; | ||
@@ -183,0 +184,0 @@ data.name = node.parent.id.name; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const util_1 = require("../util"); | ||
@@ -28,3 +29,3 @@ const getESLintCoreRule_1 = require("../util/getESLintCoreRule"); | ||
const rules = baseRule.create(context); | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
let requireSpace = true; | ||
@@ -31,0 +32,0 @@ if (typeof config === 'object') { |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const util_1 = require("../util"); | ||
@@ -49,3 +50,3 @@ exports.default = (0, util_1.createRule)({ | ||
create(context, [firstOption]) { | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
const baseConfig = typeof firstOption === 'string' ? firstOption : 'always'; | ||
@@ -52,0 +53,0 @@ const overrideConfig = typeof firstOption === 'object' ? firstOption : {}; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const util_1 = require("../util"); | ||
@@ -32,3 +33,3 @@ const getESLintCoreRule_1 = require("../util/getESLintCoreRule"); | ||
const rules = baseRule.create(context); | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
function report(operator) { | ||
@@ -35,0 +36,0 @@ context.report({ |
@@ -27,2 +27,3 @@ "use strict"; | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const tsutils = __importStar(require("ts-api-utils")); | ||
@@ -114,3 +115,3 @@ const ts = __importStar(require("typescript")); | ||
const compilerOptions = services.program.getCompilerOptions(); | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
const isStrictNullChecks = tsutils.isStrictCompilerOptionEnabled(compilerOptions, 'strictNullChecks'); | ||
@@ -117,0 +118,0 @@ if (!isStrictNullChecks && |
@@ -26,2 +26,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const tsutils = __importStar(require("ts-api-utils")); | ||
@@ -35,7 +36,18 @@ const ts = __importStar(require("typescript")); | ||
docs: { | ||
description: 'Require switch-case statements to be exhaustive with union type', | ||
description: 'Require switch-case statements to be exhaustive', | ||
requiresTypeChecking: true, | ||
}, | ||
hasSuggestions: true, | ||
schema: [], | ||
schema: [ | ||
{ | ||
type: 'object', | ||
additionalProperties: false, | ||
properties: { | ||
requireDefaultForNonUnion: { | ||
description: `If 'true', require a 'default' clause for switches on non-union types.`, | ||
type: 'boolean', | ||
}, | ||
}, | ||
}, | ||
], | ||
messages: { | ||
@@ -46,9 +58,10 @@ switchIsNotExhaustive: 'Switch is not exhaustive. Cases not matched: {{missingBranches}}', | ||
}, | ||
defaultOptions: [], | ||
create(context) { | ||
const sourceCode = context.getSourceCode(); | ||
defaultOptions: [{ requireDefaultForNonUnion: false }], | ||
create(context, [{ requireDefaultForNonUnion }]) { | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
const services = (0, util_1.getParserServices)(context); | ||
const checker = services.program.getTypeChecker(); | ||
const compilerOptions = services.program.getCompilerOptions(); | ||
function fixSwitch(fixer, node, missingBranchTypes, symbolName) { | ||
function fixSwitch(fixer, node, missingBranchTypes, // null means default branch | ||
symbolName) { | ||
const lastCase = node.cases.length > 0 ? node.cases[node.cases.length - 1] : null; | ||
@@ -62,2 +75,6 @@ const caseIndent = lastCase | ||
for (const missingBranchType of missingBranchTypes) { | ||
if (missingBranchType == null) { | ||
missingCases.push(`default: { throw new Error('default case') }`); | ||
continue; | ||
} | ||
// While running this rule on checker.ts of TypeScript project | ||
@@ -81,6 +98,11 @@ // the fix introduced a compiler error due to: | ||
(0, util_1.requiresQuoting)(missingBranchName.toString(), compilerOptions.target)) { | ||
caseTest = `${symbolName}['${missingBranchName}']`; | ||
const escapedBranchName = missingBranchName | ||
.replace(/'/g, "\\'") | ||
.replace(/\n/g, '\\n') | ||
.replace(/\r/g, '\\r'); | ||
caseTest = `${symbolName}['${escapedBranchName}']`; | ||
} | ||
const errorMessage = `Not implemented yet: ${caseTest} case`; | ||
missingCases.push(`case ${caseTest}: { throw new Error('${errorMessage}') }`); | ||
const escapedErrorMessage = errorMessage.replace(/'/g, "\\'"); | ||
missingCases.push(`case ${caseTest}: { throw new Error('${escapedErrorMessage}') }`); | ||
} | ||
@@ -136,2 +158,22 @@ const fixString = missingCases | ||
} | ||
else if (requireDefaultForNonUnion) { | ||
const hasDefault = node.cases.some(switchCase => switchCase.test == null); | ||
if (!hasDefault) { | ||
context.report({ | ||
node: node.discriminant, | ||
messageId: 'switchIsNotExhaustive', | ||
data: { | ||
missingBranches: 'default', | ||
}, | ||
suggest: [ | ||
{ | ||
messageId: 'addMissingCases', | ||
fix(fixer) { | ||
return fixSwitch(fixer, node, [null]); | ||
}, | ||
}, | ||
], | ||
}); | ||
} | ||
} | ||
} | ||
@@ -138,0 +180,0 @@ return { |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const util_1 = require("../util"); | ||
@@ -46,3 +47,3 @@ exports.default = (0, util_1.createRule)({ | ||
let programNode; | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
const references = []; | ||
@@ -49,0 +50,0 @@ function hasMatchingReference(source) { |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const util_1 = require("../util"); | ||
@@ -13,3 +14,3 @@ function createRules(options) { | ||
...globals, | ||
...override?.colon, | ||
...override.colon, | ||
}; | ||
@@ -19,3 +20,3 @@ const arrow = { | ||
...globals, | ||
...override?.arrow, | ||
...override.arrow, | ||
}; | ||
@@ -25,6 +26,6 @@ return { | ||
arrow: arrow, | ||
variable: { ...colon, ...override?.variable }, | ||
property: { ...colon, ...override?.property }, | ||
parameter: { ...colon, ...override?.parameter }, | ||
returnType: { ...colon, ...override?.returnType }, | ||
variable: { ...colon, ...override.variable }, | ||
property: { ...colon, ...override.property }, | ||
parameter: { ...colon, ...override.parameter }, | ||
returnType: { ...colon, ...override.returnType }, | ||
}; | ||
@@ -43,3 +44,3 @@ } | ||
function getRules(rules, node) { | ||
const scope = node?.parent?.parent; | ||
const scope = node.parent.parent; | ||
if ((0, util_1.isTSFunctionType)(scope) || (0, util_1.isTSConstructorType)(scope)) { | ||
@@ -114,3 +115,3 @@ return rules.arrow; | ||
const punctuators = [':', '=>']; | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
const ruleSet = createRules(options); | ||
@@ -117,0 +118,0 @@ /** |
@@ -85,4 +85,3 @@ "use strict"; | ||
// Check TS parameter property with default value like `constructor(private param: string = 'something') {}` | ||
if (annotationNode && | ||
annotationNode.type === utils_1.AST_NODE_TYPES.AssignmentPattern) { | ||
if (annotationNode.type === utils_1.AST_NODE_TYPES.AssignmentPattern) { | ||
annotationNode = annotationNode.left; | ||
@@ -95,3 +94,3 @@ } | ||
} | ||
if (annotationNode !== undefined && !annotationNode.typeAnnotation) { | ||
if (!annotationNode.typeAnnotation) { | ||
report(param, getNodeName(param)); | ||
@@ -121,3 +120,3 @@ } | ||
ArrayPattern(node) { | ||
if (node.parent?.type === utils_1.AST_NODE_TYPES.RestElement && | ||
if (node.parent.type === utils_1.AST_NODE_TYPES.RestElement && | ||
node.parent.typeAnnotation) { | ||
@@ -129,3 +128,3 @@ return; | ||
!isAncestorHasTypeAnnotation(node) && | ||
node.parent?.type !== utils_1.AST_NODE_TYPES.AssignmentExpression) { | ||
node.parent.type !== utils_1.AST_NODE_TYPES.AssignmentExpression) { | ||
report(node); | ||
@@ -132,0 +131,0 @@ } |
@@ -27,2 +27,3 @@ "use strict"; | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const tsutils = __importStar(require("ts-api-utils")); | ||
@@ -80,3 +81,3 @@ const ts = __importStar(require("typescript")); | ||
'Object', | ||
'String', | ||
'String', // eslint-disable-line @typescript-eslint/internal/prefer-ast-types-enum | ||
'RegExp', | ||
@@ -156,3 +157,3 @@ 'Symbol', | ||
const services = (0, util_1.getParserServices)(context); | ||
const currentSourceFile = services.program.getSourceFile(context.getFilename()); | ||
const currentSourceFile = services.program.getSourceFile((0, eslint_utils_1.getFilename)(context)); | ||
function checkMethodAndReport(node, symbol) { | ||
@@ -224,8 +225,7 @@ if (!symbol) { | ||
const decl = valueDeclaration; | ||
const firstParam = decl.parameters[0]; | ||
const firstParam = decl.parameters.at(0); | ||
const firstParamIsThis = firstParam?.name.kind === ts.SyntaxKind.Identifier && | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison | ||
firstParam?.name.escapedText === 'this'; | ||
const thisArgIsVoid = firstParamIsThis && | ||
firstParam?.type?.kind === ts.SyntaxKind.VoidKeyword; | ||
firstParam.name.escapedText === 'this'; | ||
const thisArgIsVoid = firstParamIsThis && firstParam.type?.kind === ts.SyntaxKind.VoidKeyword; | ||
return { | ||
@@ -232,0 +232,0 @@ dangerous: !thisArgIsVoid && |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
const util_1 = require("../util"); | ||
@@ -38,3 +39,3 @@ exports.default = (0, util_1.createRule)({ | ||
create(context, [{ ignoreDifferentlyNamedParameters }]) { | ||
const sourceCode = context.getSourceCode(); | ||
const sourceCode = (0, eslint_utils_1.getSourceCode)(context); | ||
//---------------------------------------------------------------------- | ||
@@ -230,4 +231,3 @@ // Helpers | ||
function isTSParameterProperty(node) { | ||
return (node.type === | ||
utils_1.AST_NODE_TYPES.TSParameterProperty); | ||
return node.type === utils_1.AST_NODE_TYPES.TSParameterProperty; | ||
} | ||
@@ -234,0 +234,0 @@ function parametersAreEqual(a, b) { |
@@ -18,2 +18,3 @@ "use strict"; | ||
const utils_1 = require("@typescript-eslint/utils"); | ||
const eslint_utils_1 = require("@typescript-eslint/utils/eslint-utils"); | ||
class UnusedVarsVisitor extends scope_manager_1.Visitor { | ||
@@ -42,6 +43,6 @@ // readonly #unusedVariables = new Set<TSESLint.Scope.Variable>(); | ||
this.TSMethodSignature = this.visitFunctionTypeSignature; | ||
__classPrivateFieldSet(this, _UnusedVarsVisitor_scopeManager, utils_1.ESLintUtils.nullThrows(context.getSourceCode().scopeManager, 'Missing required scope manager'), "f"); | ||
__classPrivateFieldSet(this, _UnusedVarsVisitor_scopeManager, utils_1.ESLintUtils.nullThrows((0, eslint_utils_1.getSourceCode)(context).scopeManager, 'Missing required scope manager'), "f"); | ||
} | ||
static collectUnusedVariables(context) { | ||
const program = context.getSourceCode().ast; | ||
const program = (0, eslint_utils_1.getSourceCode)(context).ast; | ||
const cached = this.RESULTS_CACHE.get(program); | ||
@@ -180,3 +181,3 @@ if (cached) { | ||
if (node.left.type === utils_1.AST_NODE_TYPES.VariableDeclaration) { | ||
const variable = __classPrivateFieldGet(this, _UnusedVarsVisitor_scopeManager, "f").getDeclaredVariables(node.left)[0]; | ||
const variable = __classPrivateFieldGet(this, _UnusedVarsVisitor_scopeManager, "f").getDeclaredVariables(node.left).at(0); | ||
if (!variable) { | ||
@@ -326,2 +327,3 @@ return; | ||
} | ||
const LOGICAL_ASSIGNMENT_OPERATORS = new Set(['&&=', '||=', '??=']); | ||
/** | ||
@@ -527,2 +529,3 @@ * Determines if the variable is used. | ||
((parent.type === utils_1.AST_NODE_TYPES.AssignmentExpression && | ||
!LOGICAL_ASSIGNMENT_OPERATORS.has(parent.operator) && | ||
grandparent.type === utils_1.AST_NODE_TYPES.ExpressionStatement && | ||
@@ -529,0 +532,0 @@ parent.left === id) || |
@@ -28,2 +28,32 @@ "use strict"; | ||
* ``` | ||
* foo(() => 1) | ||
* ``` | ||
*/ | ||
function isFunctionArgument(parent, callee) { | ||
return (parent.type === utils_1.AST_NODE_TYPES.CallExpression && | ||
// make sure this isn't an IIFE | ||
parent.callee !== callee); | ||
} | ||
/** | ||
* Checks if a node is type-constrained in JSX | ||
* ``` | ||
* <Foo x={() => {}} /> | ||
* <Bar>{() => {}}</Bar> | ||
* <Baz {...props} /> | ||
* ``` | ||
*/ | ||
function isTypedJSX(node) { | ||
return (node.type === utils_1.AST_NODE_TYPES.JSXExpressionContainer || | ||
node.type === utils_1.AST_NODE_TYPES.JSXSpreadAttribute); | ||
} | ||
function isTypedParent(parent, callee) { | ||
return ((0, astUtils_1.isTypeAssertion)(parent) || | ||
isVariableDeclaratorWithTypeAnnotation(parent) || | ||
isPropertyDefinitionWithTypeAnnotation(parent) || | ||
isFunctionArgument(parent, callee) || | ||
isTypedJSX(parent)); | ||
} | ||
/** | ||
* Checks if a node belongs to: | ||
* ``` | ||
* new Foo(() => {}) | ||
@@ -49,16 +79,8 @@ * ^^^^^^^^ | ||
} | ||
const objectExpr = property.parent; // this shouldn't happen, checking just in case | ||
/* istanbul ignore if */ if (!objectExpr || | ||
objectExpr.type !== utils_1.AST_NODE_TYPES.ObjectExpression) { | ||
const objectExpr = property.parent; | ||
if (objectExpr.type !== utils_1.AST_NODE_TYPES.ObjectExpression) { | ||
return false; | ||
} | ||
const parent = objectExpr.parent; // this shouldn't happen, checking just in case | ||
/* istanbul ignore if */ if (!parent) { | ||
return false; | ||
} | ||
return ((0, astUtils_1.isTypeAssertion)(parent) || | ||
isPropertyDefinitionWithTypeAnnotation(parent) || | ||
isVariableDeclaratorWithTypeAnnotation(parent) || | ||
isFunctionArgument(parent) || | ||
isPropertyOfObjectWithType(parent)); | ||
const parent = objectExpr.parent; | ||
return isTypedParent(parent) || isPropertyOfObjectWithType(parent); | ||
} | ||
@@ -77,6 +99,2 @@ /** | ||
function doesImmediatelyReturnFunctionExpression({ body, }) { | ||
// Should always have a body; really checking just in case | ||
/* istanbul ignore if */ if (!body) { | ||
return false; | ||
} | ||
// Check if body is a block with a single statement | ||
@@ -98,13 +116,2 @@ if (body.type === utils_1.AST_NODE_TYPES.BlockStatement && body.body.length === 1) { | ||
/** | ||
* Checks if a node belongs to: | ||
* ``` | ||
* foo(() => 1) | ||
* ``` | ||
*/ | ||
function isFunctionArgument(parent, callee) { | ||
return (parent.type === utils_1.AST_NODE_TYPES.CallExpression && | ||
// make sure this isn't an IIFE | ||
parent.callee !== callee); | ||
} | ||
/** | ||
* Checks if a function belongs to: | ||
@@ -137,7 +144,4 @@ * ``` | ||
} | ||
return ((0, astUtils_1.isTypeAssertion)(parent) || | ||
isVariableDeclaratorWithTypeAnnotation(parent) || | ||
isPropertyDefinitionWithTypeAnnotation(parent) || | ||
return (isTypedParent(parent, node) || | ||
isPropertyOfObjectWithType(parent) || | ||
isFunctionArgument(parent, node) || | ||
isConstructorArgument(parent)); | ||
@@ -205,8 +209,8 @@ } | ||
let ancestor = node.parent; | ||
if (ancestor?.type === utils_1.AST_NODE_TYPES.Property) { | ||
if (ancestor.type === utils_1.AST_NODE_TYPES.Property) { | ||
ancestor = ancestor.value; | ||
} | ||
// if the ancestor is not a return, then this function was not returned at all, so we can exit early | ||
const isReturnStatement = ancestor?.type === utils_1.AST_NODE_TYPES.ReturnStatement; | ||
const isBodylessArrow = ancestor?.type === utils_1.AST_NODE_TYPES.ArrowFunctionExpression && | ||
const isReturnStatement = ancestor.type === utils_1.AST_NODE_TYPES.ReturnStatement; | ||
const isBodylessArrow = ancestor.type === utils_1.AST_NODE_TYPES.ArrowFunctionExpression && | ||
ancestor.body.type !== utils_1.AST_NODE_TYPES.BlockStatement; | ||
@@ -213,0 +217,0 @@ if (!isReturnStatement && !isBodylessArrow) { |
@@ -6,3 +6,3 @@ "use strict"; | ||
function getThisExpression(node) { | ||
while (node) { | ||
while (true) { | ||
if (node.type === utils_1.AST_NODE_TYPES.CallExpression) { | ||
@@ -9,0 +9,0 @@ node = node.callee; |
@@ -154,3 +154,3 @@ "use strict"; | ||
function formatWordList(words) { | ||
if (!words?.length) { | ||
if (!words.length) { | ||
return ''; | ||
@@ -157,0 +157,0 @@ } |
@@ -93,2 +93,8 @@ --- | ||
If you don't care about the general structure of the code, then you will not need this rule. | ||
It can sometimes be useful to place overload signatures alongside other meaningful parts of a type. | ||
For example, if each of a function's overloads corresponds to a different property, you might wish to put each overloads next to its corresponding property. | ||
You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. | ||
## Related To | ||
- [`unified-signatures`](./unified-signatures.md) |
@@ -104,1 +104,9 @@ --- | ||
| `generic` | `generic` | `Array<number>` | `Array<Foo & Bar>` | `ReadonlyArray<number>` | `ReadonlyArray<Foo & Bar>` | | ||
## When Not To Use It | ||
This rule is purely a stylistic rule for maintaining consistency in your project. | ||
You can turn it off if you don't want to keep a consistent style for array types. | ||
However, keep in mind that inconsistent style can harm readability in a project. | ||
We recommend picking a single option for this rule that works best for your project. |
@@ -40,2 +40,4 @@ --- | ||
If you want to allow code to `await` non-Promise values. | ||
This is generally not preferred, but can sometimes be useful for visual consistency. | ||
For example, if your framework is in transition from one style of asynchronous code to another, it may be useful to include `await`s unnecessarily. | ||
This is generally not preferred but can sometimes be useful for visual consistency. | ||
You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. |
@@ -146,3 +146,4 @@ --- | ||
If you want to use all of the TypeScript directives. | ||
If your project or its dependencies were not architected with strong type safety in mind, it can be difficult to always adhere to proper TypeScript semantics. | ||
You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. | ||
@@ -149,0 +150,0 @@ ## Further Reading |
@@ -39,2 +39,2 @@ --- | ||
If you are still using TSLint. | ||
If you are still using TSLint alongside ESLint. |
@@ -128,1 +128,6 @@ --- | ||
``` | ||
## When Not To Use It | ||
If your project is a rare one that intentionally deals with the class equivalents of primitives, it might not be worthwhile to enable the default `ban-types` options. | ||
You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. |
@@ -105,3 +105,2 @@ --- | ||
When you have no strong preference, or do not wish to enforce a particular style | ||
for how literal values are exposed by your classes. | ||
When you have no strong preference, or do not wish to enforce a particular style for how literal values are exposed by your classes. |
@@ -19,3 +19,3 @@ --- | ||
ignoreOverrideMethods?: boolean; | ||
ignoreClassesThatImplementAnInterface?: boolean; | ||
ignoreClassesThatImplementAnInterface?: boolean | 'public-fields'; | ||
} | ||
@@ -45,6 +45,12 @@ | ||
Makes the rule ignore all class members that are defined within a class that `implements` a type. | ||
Makes the rule ignore class members that are defined within a class that `implements` a type. | ||
If specified, it can be either: | ||
- `true`: Ignore all classes that implement an interface | ||
- `'public-fields'`: Ignore only the public fields of classes that implement an interface | ||
It's important to note that this option does not only apply to members defined in the interface as that would require type information. | ||
#### `true` | ||
Example of a correct code when `ignoreClassesThatImplementAnInterface` is set to `true`: | ||
@@ -58,1 +64,36 @@ | ||
``` | ||
#### `'public-fields'` | ||
Example of a incorrect code when `ignoreClassesThatImplementAnInterface` is set to `'public-fields'`: | ||
<!--tabs--> | ||
##### ❌ Incorrect | ||
```ts | ||
class X implements Y { | ||
method() {} | ||
property = () => {}; | ||
private privateMethod() {} | ||
private privateProperty = () => {}; | ||
protected privateMethod() {} | ||
protected privateProperty = () => {}; | ||
} | ||
``` | ||
##### ✅ Correct | ||
```ts | ||
class X implements Y { | ||
method() {} | ||
property = () => {}; | ||
} | ||
``` | ||
## When Not To Use It | ||
If your project dynamically changes `this` scopes around in a way TypeScript has difficulties modeling, this rule may not be viable to use. | ||
You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. |
@@ -74,1 +74,4 @@ --- | ||
You can turn this rule off if you don't want to enforce one kind of generic constructor style over the other. | ||
However, keep in mind that inconsistent style can harm readability in a project. | ||
We recommend picking a single option for this rule that works best for your project. |
@@ -73,1 +73,9 @@ --- | ||
``` | ||
## When Not To Use It | ||
This rule is purely a stylistic rule for maintaining consistency in your project. | ||
You can turn it off if you don't want to keep a consistent style for indexed object types. | ||
However, keep in mind that inconsistent style can harm readability in a project. | ||
We recommend picking a single option for this rule that works best for your project. |
@@ -109,1 +109,4 @@ --- | ||
If you do not want to enforce consistent type assertions. | ||
However, keep in mind that inconsistent style can harm readability in a project. | ||
We recommend picking a single option for this rule that works best for your project. |
@@ -74,2 +74,9 @@ --- | ||
If you specifically want to use an interface or type literal for stylistic reasons, you can disable this rule. | ||
If you specifically want to use an interface or type literal for stylistic reasons, you can avoid this rule. | ||
However, keep in mind that inconsistent style can harm readability in a project. | ||
We recommend picking a single option for this rule that works best for your project. | ||
There are also subtle differences between `Record` and `interface` that can be difficult to catch statically. | ||
For example, if your project is a dependency of another project that relies on a specific type definition style, this rule may be counterproductive. | ||
You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. |
@@ -99,3 +99,8 @@ --- | ||
- If you specifically want to use both export kinds for stylistic reasons, you can disable this rule. | ||
- If you use `--isolatedModules` the compiler would error if a type is not re-exported using `export type`. If you also don't wish to enforce one style over the other, you can disable this rule. | ||
If you use `--isolatedModules` the compiler would error if a type is not re-exported using `export type`. | ||
This rule may be less useful in those cases. | ||
If you specifically want to use both export kinds for stylistic reasons, or don't wish to enforce one style over the other, you can avoid this rule. | ||
However, keep in mind that inconsistent style can harm readability in a project. | ||
We recommend picking a single option for this rule that works best for your project. |
@@ -99,4 +99,7 @@ --- | ||
- If you specifically want to use both import kinds for stylistic reasons, you can disable this rule. | ||
If you specifically want to use both import kinds for stylistic reasons, or don't wish to enforce one style over the other, you can avoid this rule. | ||
However, keep in mind that inconsistent style can harm readability in a project. | ||
We recommend picking a single option for this rule that works best for your project. | ||
## Related To | ||
@@ -103,0 +106,0 @@ |
@@ -76,1 +76,8 @@ --- | ||
If the TypeScript compiler option `noPropertyAccessFromIndexSignature` is set to `true`, then the above code is always allowed, even if `allowIndexSignaturePropertyAccess` is `false`. | ||
## When Not To Use It | ||
If you specifically want to use both member access kinds for stylistic reasons, or don't wish to enforce one style over the other, you can avoid this rule. | ||
However, keep in mind that inconsistent style can harm readability in a project. | ||
We recommend picking a single option for this rule that works best for your project. |
@@ -175,2 +175,6 @@ --- | ||
}); | ||
const Comp: FC = () => { | ||
return <button onClick={() => {}} />; | ||
}; | ||
``` | ||
@@ -317,4 +321,3 @@ | ||
If you don't wish to prevent calling code from using function return values in unexpected ways, then | ||
you will not need this rule. | ||
If you don't find the added cost of explicitly writing function return types to be worth the visual clarity, or your project is not large enough for it to be a factor in type checking performance, then you will not need this rule. | ||
@@ -321,0 +324,0 @@ ## Further Reading |
@@ -336,6 +336,10 @@ --- | ||
If you think defaulting to public is a good default, then you should consider using the `no-public` setting. If you want to mix implicit and explicit public members then disable this rule. | ||
If you think defaulting to public is a good default, then you should consider using the `no-public` setting. | ||
If you want to mix implicit and explicit public members then you can disable this rule. | ||
However, keep in mind that inconsistent style can harm readability in a project. | ||
We recommend picking a single option for this rule that works best for your project. | ||
## Further Reading | ||
- TypeScript [Accessibility Modifiers Handbook Docs](https://www.typescriptlang.org/docs/handbook/2/classes.html#member-visibility) |
@@ -246,3 +246,3 @@ --- | ||
If you wish to make sure all functions have explicit return types, as opposed to only the module boundaries, you can use [explicit-function-return-type](./explicit-function-return-type.md) | ||
If your project is not used by downstream consumers that are sensitive to API types, you can disable this rule. | ||
@@ -252,1 +252,5 @@ ## Further Reading | ||
- TypeScript [Functions](https://www.typescriptlang.org/docs/handbook/functions.html#function-types) | ||
## Related To | ||
- [explicit-function-return-type](./explicit-function-return-type.md) |
@@ -161,2 +161,5 @@ --- | ||
If you don't care about enforcing a consistent member delimiter in interfaces and type literals, then you will not need this rule. | ||
If you specifically want to use both member delimiter kinds for stylistic reasons, or don't wish to enforce one style over the other, you can avoid this rule. | ||
However, keep in mind that inconsistent style can harm readability in a project. | ||
We recommend picking a single option for this rule that works best for your project. |
@@ -129,2 +129,33 @@ --- | ||
// Accessors | ||
"public-static-accessor", | ||
"protected-static-accessor", | ||
"private-static-accessor", | ||
"#private-static-accessor", | ||
"public-decorated-accessor", | ||
"protected-decorated-accessor", | ||
"private-decorated-accessor", | ||
"public-instance-accessor", | ||
"protected-instance-accessor", | ||
"private-instance-accessor", | ||
"#private-instance-accessor", | ||
"public-abstract-accessor", | ||
"protected-abstract-accessor", | ||
"public-accessor", | ||
"protected-accessor", | ||
"private-accessor", | ||
"#private-accessor", | ||
"static-accessor", | ||
"instance-accessor", | ||
"abstract-accessor", | ||
"decorated-accessor", | ||
"accessor", | ||
// Getters | ||
@@ -131,0 +162,0 @@ "public-static-get", |
@@ -111,1 +111,4 @@ --- | ||
If you don't want to enforce a particular style for object/interface function types, and/or if you don't use `strictFunctionTypes`, then you don't need this rule. | ||
However, keep in mind that inconsistent style can harm readability in a project. | ||
We recommend picking a single option for this rule that works best for your project. |
@@ -714,2 +714,9 @@ --- | ||
If you do not want to enforce naming conventions for anything. | ||
This rule can be very strict. | ||
If you don't have strong needs for enforcing naming conventions, we recommend using it only to flag very egregious violations of your naming standards. | ||
Consider documenting your naming conventions and enforcing them in code review if you have processes like that. | ||
If you do not want to enforce naming conventions for anything, you can disable this rule. | ||
However, keep in mind that inconsistent style can harm readability in a project. | ||
We recommend that if you care about naming conventions, pick a single option for this rule that works best for your project. |
@@ -79,3 +79,3 @@ --- | ||
If you don't mind `"[object Object]"` in your strings, then you will not need this rule. | ||
If you don't mind a risk of `"[object Object]"` or incorrect type coercions in your values, then you will not need this rule. | ||
@@ -82,0 +82,0 @@ ## Related To |
@@ -116,2 +116,2 @@ --- | ||
If you don't care about being explicit about the void type in actual code then don't use this rule. | ||
Also, if you prefer concise coding style then also don't use it. | ||
Also, if you strongly prefer a concise coding style more strongly than any fear of `void`-related bugs then you can avoid this rule. |
@@ -51,1 +51,9 @@ --- | ||
``` | ||
## When Not To Use It | ||
It can sometimes be useful to include duplicate enum members for very specific use cases. | ||
For example, when renaming an enum member, it can sometimes be useful to keep the old name until a scheduled major breaking change. | ||
You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. | ||
In general, if your project intentionally duplicates enum member values, you can avoid this rule. |
@@ -60,1 +60,8 @@ --- | ||
When set to true, duplicate checks on union type constituents are ignored. | ||
## When Not To Use It | ||
It can sometimes be useful for the sake of documentation to include aliases for the same type. | ||
You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. | ||
> In some of those cases, [branded types](https://basarat.gitbook.io/typescript/main-1/nominaltyping#using-interfaces) might be a type-safe way to represent the underlying data types. |
@@ -50,5 +50,5 @@ --- | ||
When you know your keys are safe to delete, this rule can be unnecessary. | ||
Some environments such as older browsers might not support `Map` and `Set`. | ||
You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. | ||
Do not consider this rule as performance advice before profiling your code's bottlenecks. | ||
Even repeated minor performance slowdowns likely do not significantly affect your application's general perceived speed. |
@@ -87,1 +87,10 @@ --- | ||
``` | ||
## When Not To Use It | ||
If you are working with external APIs that require functions even if they do nothing, then you may want to avoid this rule. | ||
You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. | ||
Test code often violates this rule as well. | ||
If your testing setup doesn't support "mock" or "spy" functions such as [`jest.fn()`](https://jestjs.io/docs/mock-functions), [`sinon.spy()`](https://sinonjs.org/releases/latest/spies), or [`vi.fn()`](https://vitest.dev/guide/mocking.html), you may wish to disable this rule in test files. | ||
Again, if those cases aren't extremely common, you might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule in test files. |
@@ -141,2 +141,4 @@ --- | ||
You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. | ||
## Related To | ||
@@ -152,3 +154,5 @@ | ||
- TypeScript [`any` type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#any) | ||
- TypeScript's [`unknown` type](https://www.typescriptlang.org/docs/handbook/2/functions.html#unknown) | ||
- TypeScript [`any` type documentation](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#any) | ||
- TypeScript [`unknown` type release notes](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-0.html#new-unknown-top-type) |
@@ -53,1 +53,3 @@ --- | ||
``` | ||
<!-- Intentionally Omitted: When Not To Use It --> |
@@ -294,2 +294,3 @@ --- | ||
You can disable this rule if you are unable -or unwilling- to switch off using classes as namespaces. | ||
If your project was set up before modern class and namespace practices, and you don't have the time to switch over, you might not be practically able to use this rule. | ||
You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. |
@@ -102,3 +102,5 @@ --- | ||
If you do not use Promise-like values in your codebase, or want to allow them to remain unhandled. | ||
This rule can be difficult to enable on large existing projects that set up many floating Promises. | ||
Alternately, if you're not worried about crashes from floating or misused Promises -such as if you have global unhandled Promise handlers registered- then in some cases it may be safe to not use this rule. | ||
You might consider using `void`s and/or [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. | ||
@@ -105,0 +107,0 @@ ## Related To |
@@ -56,2 +56,3 @@ --- | ||
If you want to iterate through a loop using the indices in an array as strings, you can turn off this rule. | ||
If your project is a rare one that intentionally loops over string indices of arrays, you can turn off this rule. | ||
You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. |
@@ -101,2 +101,3 @@ --- | ||
If you want to allow `new Function()` or `setTimeout()`, `setInterval()`, `setImmediate()` and `execScript()` with string arguments, then you can safely disable this rule. | ||
If your project is a rare one that needs to allow `new Function()` or `setTimeout()`, `setInterval()`, `setImmediate()` and `execScript()` with string arguments, then you can disable this rule. | ||
You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. |
@@ -68,4 +68,3 @@ --- | ||
- If you want to leave behind side effect imports, then you shouldn't use this rule. | ||
- If you're not using TypeScript 5.0's `verbatimModuleSyntax` option, then you don't need this rule. | ||
If you're not using TypeScript 5.0's `verbatimModuleSyntax` option and your project is built with a bundler that manages import side effects for you, this rule may not be as useful for you. | ||
@@ -72,0 +71,0 @@ ## Related To |
@@ -99,6 +99,6 @@ --- | ||
If you do not want to enforce inferred types. | ||
If you strongly prefer to have explicit types regardless of whether they can be inferred, this rule may not be for you. | ||
## Further Reading | ||
TypeScript [Inference](https://www.typescriptlang.org/docs/handbook/type-inference.html) | ||
- [TpeScript Inference](https://www.typescriptlang.org/docs/handbook/type-inference.html) |
@@ -112,3 +112,2 @@ --- | ||
If you don't care about if `void` is used with other types, | ||
or in invalid places, then you don't need this rule. | ||
If you don't care about if `void` is used with other types, or in invalid places, then you don't need this rule. |
@@ -114,1 +114,7 @@ --- | ||
``` | ||
## When Not To Use It | ||
If your project frequently deals with constant numbers and you don't wish to take up extra space to declare them, this rule might not be for you. | ||
We recommend at least using descriptive comments and/or names to describe constants. | ||
You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) instead of completely disabling this rule. |
@@ -48,1 +48,5 @@ --- | ||
`checkNever: true` will suggest removing `void` when the argument has type `never`. | ||
## When Not To Use It | ||
If you don't mind extra `void`s in your project, you can avoid this rule. |
@@ -46,2 +46,3 @@ --- | ||
If you intentionally want a class with a `new` method, and you're confident nobody working in your code will mistake it with a constructor. | ||
If you intentionally want a class with a `new` method, and you're confident nobody working in your code will mistake it with a constructor, you might not want this rule. | ||
You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. |
@@ -236,4 +236,5 @@ --- | ||
If you do not use Promises in your codebase or are not concerned with possible | ||
misuses of them outside of what the TypeScript compiler will check. | ||
This rule can be difficult to enable on large existing projects that set up many misused Promises. | ||
Alternately, if you're not worried about crashes from floating or misused Promises -such as if you have global unhandled Promise handlers registered- then in some cases it may be safe to not use this rule. | ||
You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. | ||
@@ -240,0 +241,0 @@ ## Further Reading |
@@ -123,3 +123,5 @@ --- | ||
If you are using the ES2015 module syntax, then you will not need this rule. | ||
If your project was architected before modern modules and namespaces, it may be difficult to migrate off of namespaces. | ||
In that case you may not be able to use this rule for parts of your project. | ||
You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. | ||
@@ -126,0 +128,0 @@ ## Further Reading |
@@ -46,2 +46,7 @@ --- | ||
## When Not To Use It | ||
If your project's types don't yet fully describe whether certain values may be nullable, such as if you're transitioning to `strictNullChecks`, this rule might create many false reports. | ||
You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. | ||
## Further Reading | ||
@@ -48,0 +53,0 @@ |
@@ -32,2 +32,7 @@ --- | ||
## When Not To Use It | ||
If your project's types don't yet fully describe whether certain values may be nullable, such as if you're transitioning to `strictNullChecks`, this rule might create many false reports. | ||
You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. | ||
## Further Reading | ||
@@ -34,0 +39,0 @@ |
@@ -41,3 +41,3 @@ --- | ||
If your project does not use the `strictNullChecks` compiler option, this rule is likely useless to you. | ||
If your code is often wildly incorrect with respect to strict null-checking, your code may not yet be ready for this rule. | ||
If your project's types don't yet fully describe whether certain values may be nullable, such as if you're transitioning to `strictNullChecks`, this rule might create many false reports. | ||
You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. |
@@ -73,2 +73,16 @@ --- | ||
## When Not To Use It | ||
Some projects choose to occasionally intentionally include a redundant type constituent for documentation purposes. | ||
For example, the following code includes `string` in a union even though the `unknown` makes it redundant: | ||
```ts | ||
/** | ||
* Normally a string name, but sometimes arbitrary unknown data. | ||
*/ | ||
type NameOrOther = string | unknown; | ||
``` | ||
If you strongly feel a preference for these unnecessary type constituents, this rule might not be for you. | ||
## Further Reading | ||
@@ -75,0 +89,0 @@ |
@@ -33,3 +33,4 @@ --- | ||
If you don't care about using newer module syntax, then you will not need this rule. | ||
If your project frequently uses older CommonJS `require`s, then this rule might not be applicable to you. | ||
If only a subset of your project uses `require`s then you might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. | ||
@@ -36,0 +37,0 @@ ## Related To |
@@ -38,2 +38,3 @@ --- | ||
If you need to assign `this` to variables, you shouldn’t use this rule. | ||
If your project is structured in a way that it needs to assign `this` to variables, this rule is likely not for you. | ||
If only a subset of your project assigns `this` to variables then you might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. |
@@ -112,1 +112,3 @@ --- | ||
``` | ||
<!-- Intentionally omitted: When Not To Use It --> |
@@ -609,9 +609,6 @@ --- | ||
## When Not To Use It | ||
<!-- Intentionally Omitted: When Not To Use It --> | ||
When you can't express some shape with an interface or you need to use a union, tuple type, | ||
callback, etc. that would cause the code to be unreadable or impractical. | ||
## Further Reading | ||
- [Advanced Types](https://www.typescriptlang.org/docs/handbook/advanced-types.html) |
@@ -129,3 +129,3 @@ --- | ||
## Not To Use It | ||
## When Not To Use It | ||
@@ -132,0 +132,0 @@ Do not use this rule when `strictNullChecks` is disabled. |
@@ -98,3 +98,4 @@ --- | ||
The main downside to using this rule is the need for type information. | ||
If your project is not accurately typed, such as if it's in the process of being converted to TypeScript or is susceptible to [trade-offs in control flow analysis](https://github.com/Microsoft/TypeScript/issues/9998), it may be difficult to enable this rule for particularly non-type-safe areas of code. | ||
You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. | ||
@@ -101,0 +102,0 @@ This rule has a known edge case of triggering on conditions that were modified within function calls (as side effects). |
@@ -51,2 +51,2 @@ --- | ||
If you don't care about having unneeded enum or namespace qualifiers, then you don't need to use this rule. | ||
If you explicitly prefer to use fully qualified names, such as for explicitness, then you don't need to use this rule. |
@@ -74,1 +74,5 @@ --- | ||
``` | ||
## When Not To Use It | ||
If you prefer explicitly specifying type parameters even when they are equal to the default, you can skip this rule. |
@@ -81,4 +81,14 @@ --- | ||
## When Not To Use It | ||
If your codebase has many existing `any`s or areas of unsafe code, it may be difficult to enable this rule. | ||
It may be easier to skip the `no-unsafe-*` rules pending increasing type safety in unsafe areas of your project. | ||
You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. | ||
## Related To | ||
- [`no-explicit-any`](./no-explicit-any.md) | ||
- [`no-unsafe-assignment`](./no-unsafe-assignment.md) | ||
- [`no-unsafe-call`](./no-unsafe-call.md) | ||
- [`no-unsafe-member-access`](./no-unsafe-member-access.md) | ||
- [`no-unsafe-return`](./no-unsafe-return.md) |
@@ -84,4 +84,14 @@ --- | ||
## When Not To Use It | ||
If your codebase has many existing `any`s or areas of unsafe code, it may be difficult to enable this rule. | ||
It may be easier to skip the `no-unsafe-*` rules pending increasing type safety in unsafe areas of your project. | ||
You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. | ||
## Related To | ||
- [`no-explicit-any`](./no-explicit-any.md) | ||
- [`no-unsafe-argument`](./no-unsafe-argument.md) | ||
- [`no-unsafe-call`](./no-unsafe-call.md) | ||
- [`no-unsafe-member-access`](./no-unsafe-member-access.md) | ||
- [`no-unsafe-return`](./no-unsafe-return.md) |
@@ -56,4 +56,14 @@ --- | ||
## When Not To Use It | ||
If your codebase has many existing `any`s or areas of unsafe code, it may be difficult to enable this rule. | ||
It may be easier to skip the `no-unsafe-*` rules pending increasing type safety in unsafe areas of your project. | ||
You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. | ||
## Related To | ||
- [`no-explicit-any`](./no-explicit-any.md) | ||
- [`no-unsafe-argument`](./no-unsafe-argument.md) | ||
- [`no-unsafe-assignment`](./no-unsafe-assignment.md) | ||
- [`no-unsafe-member-access`](./no-unsafe-member-access.md) | ||
- [`no-unsafe-return`](./no-unsafe-return.md) |
@@ -52,4 +52,9 @@ --- | ||
## When Not To Use It | ||
If your project intentionally defines classes and interfaces with unsafe declaration merging patterns, this rule might not be for you. | ||
You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. | ||
## Further Reading | ||
- [Declaration Merging](https://www.typescriptlang.org/docs/handbook/declaration-merging.html) |
@@ -9,18 +9,20 @@ --- | ||
The TypeScript compiler can be surprisingly lenient when working with enums. | ||
For example, it will allow you to compare enum values against numbers even though they might not have any type overlap: | ||
The TypeScript compiler can be surprisingly lenient when working with enums. String enums are widely considered to be safer than number enums, but even string enums have some pitfalls. For example, it is allowed to compare enum values against literals: | ||
```ts | ||
enum Fruit { | ||
Apple, | ||
Banana, | ||
enum Vegetable { | ||
Asparagus = 'asparagus', | ||
} | ||
declare let fruit: Fruit; | ||
declare const vegetable: Vegetable; | ||
fruit === 999; // No error | ||
vegetable === 'asparagus'; // No error | ||
``` | ||
This rule flags when an enum typed value is compared to a non-enum `number`. | ||
The above code snippet should instead be written as `vegetable === Vegetable.Asparagus`. Allowing literals in comparisons subverts the point of using enums in the first place. By enforcing comparisons with properly typed enums: | ||
- It makes a codebase more resilient to enum members changing values. | ||
- It allows for code IDEs to use the "Rename Symbol" feature to quickly rename an enum. | ||
- It aligns code to the proper enum semantics of referring to them by name and treating their values as implementation details. | ||
## Examples | ||
@@ -39,3 +41,3 @@ | ||
fruit === 999; | ||
fruit === 0; | ||
``` | ||
@@ -62,3 +64,3 @@ | ||
fruit === Fruit.Banana; | ||
fruit === Fruit.Apple; | ||
``` | ||
@@ -81,1 +83,4 @@ | ||
If you don't mind number and/or literal string constants being compared against enums, you likely don't need this rule. | ||
Separately, in the rare case of relying on an third party enums that are only imported as `type`s, it may be difficult to adhere to this rule. | ||
You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. |
@@ -62,4 +62,14 @@ --- | ||
## When Not To Use It | ||
If your codebase has many existing `any`s or areas of unsafe code, it may be difficult to enable this rule. | ||
It may be easier to skip the `no-unsafe-*` rules pending increasing type safety in unsafe areas of your project. | ||
You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. | ||
## Related To | ||
- [`no-explicit-any`](./no-explicit-any.md) | ||
- [`no-unsafe-argument`](./no-unsafe-argument.md) | ||
- [`no-unsafe-assignment`](./no-unsafe-assignment.md) | ||
- [`no-unsafe-call`](./no-unsafe-call.md) | ||
- [`no-unsafe-return`](./no-unsafe-return.md) |
@@ -101,4 +101,14 @@ --- | ||
## When Not To Use It | ||
If your codebase has many existing `any`s or areas of unsafe code, it may be difficult to enable this rule. | ||
It may be easier to skip the `no-unsafe-*` rules pending increasing type safety in unsafe areas of your project. | ||
You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. | ||
## Related To | ||
- [`no-explicit-any`](./no-explicit-any.md) | ||
- [`no-unsafe-argument`](./no-unsafe-argument.md) | ||
- [`no-unsafe-assignment`](./no-unsafe-assignment.md) | ||
- [`no-unsafe-call`](./no-unsafe-call.md) | ||
- [`no-unsafe-member-access`](./no-unsafe-member-access.md) |
@@ -44,1 +44,5 @@ --- | ||
``` | ||
## When Not To Use It | ||
If you don't mind an empty `export {}` at the bottom of files, you likely don't need this rule. |
@@ -33,3 +33,4 @@ --- | ||
If you don't care about using newer module syntax, then you will not need this rule. | ||
If your project frequently uses older CommonJS `require`s, then this rule might not be applicable to you. | ||
If only a subset of your project uses `require`s then you might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. | ||
@@ -36,0 +37,0 @@ ## Related To |
@@ -41,2 +41,2 @@ --- | ||
If you don't mind having unnecessarily verbose type casts, you can avoid this rule. | ||
If you don't mind having unnecessarily verbose type assertions, you can avoid this rule. |
@@ -485,2 +485,5 @@ --- | ||
If you don't care about the using parameter properties in constructors, then you will not need this rule. | ||
If you don't care about which style of parameter properties in constructors is used in your classes, then you will not need this rule. | ||
However, keep in mind that inconsistent style can harm readability in a project. | ||
We recommend picking a single option for this rule that works best for your project. |
@@ -44,2 +44,5 @@ --- | ||
If you are using TypeScript < 3.4 | ||
If you don't care about which style of literals assertions is used in your code, then you will not need this rule. | ||
However, keep in mind that inconsistent style can harm readability in a project. | ||
We recommend picking a single option for this rule that works best for your project. |
@@ -44,4 +44,2 @@ --- | ||
## When Not To Use It | ||
If you transpile for browsers that do not support for-of loops, you may wish to use traditional for loops that produce more compact code. | ||
<!-- Intentionally Omitted: When Not To Use It --> |
@@ -87,3 +87,3 @@ --- | ||
If you specifically want to use an interface or type literal with a single call signature for stylistic reasons, you can disable this rule. | ||
If you specifically want to use an interface or type literal with a single call signature for stylistic reasons, you can avoid this rule. | ||
@@ -90,0 +90,0 @@ This rule has a known edge case of sometimes triggering on global augmentations such as `interface Function`. |
@@ -75,4 +75,2 @@ --- | ||
## When Not To Use It | ||
If you don't want to suggest `includes`, you can safely turn this rule off. | ||
<!-- Intentionally Omitted: When Not To Use It --> |
@@ -101,2 +101,2 @@ --- | ||
If you want use anything other than simple literals as an enum value. | ||
If you want use anything other than simple literals as an enum value, this rule might not be for you. |
@@ -41,3 +41,3 @@ --- | ||
If you are using the ES2015 module syntax, then you will not need this rule. | ||
If you are not using TypeScript's older `module`/`namespace` keywords, then you will not need this rule. | ||
@@ -44,0 +44,0 @@ ## Further Reading |
@@ -257,3 +257,4 @@ --- | ||
If you don't mind using more explicit `&&`s/`||`s, you don't need this rule. | ||
If your project is not accurately typed, such as if it's in the process of being converted to TypeScript or is susceptible to [trade-offs in control flow analysis](https://github.com/Microsoft/TypeScript/issues/9998), it may be difficult to enable this rule for particularly non-type-safe areas of code. | ||
You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. | ||
@@ -260,0 +261,0 @@ ## Further Reading |
@@ -383,1 +383,5 @@ --- | ||
``` | ||
## When Not To Use It | ||
If your project does not attempt to enforce strong immutability guarantees of parameters, you can avoid this rule. |
@@ -96,1 +96,5 @@ --- | ||
``` | ||
## When Not To Use It | ||
If you aren't trying to enforce strong immutability guarantees, this rule may be too restrictive for your project. |
@@ -58,2 +58,4 @@ --- | ||
If you don't want to use typechecking in your linting, you can't use this rule. | ||
This rule can sometimes be difficult to work around when creating objects using a `.reduce`. | ||
See [[prefer-reduce-type-parameter] unfixable reporting #3440](https://github.com/typescript-eslint/typescript-eslint/issues/3440) for more details. | ||
You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. |
@@ -57,2 +57,3 @@ --- | ||
If you don't mind that style, you can turn this rule off safely. | ||
If you don't mind which style of string checking is used, you can turn this rule off safely. | ||
However, keep in mind that inconsistent style can harm readability in a project. |
@@ -66,2 +66,3 @@ --- | ||
If you are compiling against multiple versions of TypeScript and using `@ts-ignore` to ignore version-specific type errors, this rule might get in your way. | ||
You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. | ||
@@ -68,0 +69,0 @@ ## Further Reading |
@@ -60,1 +60,6 @@ --- | ||
``` | ||
## When Not To Use It | ||
This rule can be difficult to enable on projects that use APIs which require functions to always be `async`. | ||
You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) along with filing issues on your dependencies for those specific situations instead of completely disabling this rule. |
@@ -78,2 +78,2 @@ --- | ||
If you understand the language specification enough, and/or only ever sort arrays in a string-like manner, you can turn this rule off safely. | ||
If you intentionally want your arrays to be always sorted in a string-like manner, you can turn this rule off safely. |
@@ -173,3 +173,3 @@ --- | ||
Examples of code for this rule with `{ skipCompoundAssignments: true }`: | ||
Examples of code for this rule with `{ skipCompoundAssignments: false }`: | ||
@@ -200,3 +200,3 @@ <!--tabs--> | ||
If you don't mind `"[object Object]"` in your strings, then you will not need this rule. | ||
If you don't mind a risk of `"[object Object]"` or incorrect type coercions in your values, then you will not need this rule. | ||
@@ -203,0 +203,0 @@ ## Related To |
@@ -114,2 +114,6 @@ --- | ||
## When Not To Use It | ||
If you're not worried about incorrectly stringifying non-string values in template literals, then you likely don't need this rule. | ||
## Related To | ||
@@ -116,0 +120,0 @@ |
@@ -102,1 +102,7 @@ --- | ||
- `nullish` - `null` and `undefined` | ||
## When Not To Use It | ||
This rule is purely a stylistic rule for maintaining consistency in your project. | ||
You can turn it off if you don't want to keep a consistent, predictable order for intersection and union types. | ||
However, keep in mind that inconsistent style can harm readability in a project. |
@@ -181,4 +181,11 @@ --- | ||
## When Not To Use It | ||
If your project isn't likely to experience bugs from falsy non-boolean values being used in logical conditions, you can skip enabling this rule. | ||
Otherwise, this rule can be quite strict around requiring exact comparisons in logical checks. | ||
If you prefer more succinct checks over more precise boolean logic, this rule might not be for you. | ||
## Related To | ||
- [no-unnecessary-condition](./no-unnecessary-condition.md) - Similar rule which reports always-truthy and always-falsy values in conditions |
--- | ||
description: 'Require switch-case statements to be exhaustive with union type.' | ||
description: 'Require switch-case statements to be exhaustive.' | ||
--- | ||
@@ -9,9 +9,15 @@ | ||
When working with union types in TypeScript, it's common to want to write a `switch` statement intended to contain a `case` for each constituent (possible type in the union). | ||
However, if the union type changes, it's easy to forget to modify the cases to account for any new types. | ||
When working with union types or enums in TypeScript, it's common to want to write a `switch` statement intended to contain a `case` for each constituent (possible type in the union or the enum). | ||
However, if the union type or the enum changes, it's easy to forget to modify the cases to account for any new types. | ||
This rule reports when a `switch` statement over a value typed as a union of literals is missing a case for any of those literal types and does not have a `default` clause. | ||
This rule reports when a `switch` statement over a value typed as a union of literals or as an enum is missing a case for any of those literal types and does not have a `default` clause. | ||
There is also an option to check the exhaustiveness of switches on non-union types by requiring a default clause. | ||
## Examples | ||
When the switch doesn't have exhaustive cases, either filling them all out or adding a default will correct the rule's complaint. | ||
Here are some examples of code working with a union of literals: | ||
<!--tabs--> | ||
@@ -31,3 +37,3 @@ | ||
const day = 'Monday' as Day; | ||
declare const day: Day; | ||
let result = 0; | ||
@@ -54,3 +60,3 @@ | ||
const day = 'Monday' as Day; | ||
declare const day: Day; | ||
let result = 0; | ||
@@ -95,3 +101,3 @@ | ||
const day = 'Monday' as Day; | ||
declare const day: Day; | ||
let result = 0; | ||
@@ -108,4 +114,99 @@ | ||
<!--/tabs--> | ||
Likewise, here are some examples of code working with an enum: | ||
<!--tabs--> | ||
### ❌ Incorrect | ||
```ts | ||
enum Fruit { | ||
Apple, | ||
Banana, | ||
Cherry, | ||
} | ||
declare const fruit: Fruit; | ||
switch (fruit) { | ||
case Fruit.Apple: | ||
console.log('an apple'); | ||
break; | ||
} | ||
``` | ||
### ✅ Correct | ||
```ts | ||
enum Fruit { | ||
Apple, | ||
Banana, | ||
Cherry, | ||
} | ||
declare const fruit: Fruit; | ||
switch (fruit) { | ||
case Fruit.Apple: | ||
console.log('an apple'); | ||
break; | ||
case Fruit.Banana: | ||
console.log('a banana'); | ||
break; | ||
case Fruit.Cherry: | ||
console.log('a cherry'); | ||
break; | ||
} | ||
``` | ||
### ✅ Correct | ||
```ts | ||
enum Fruit { | ||
Apple, | ||
Banana, | ||
Cherry, | ||
} | ||
declare const fruit: Fruit; | ||
switch (fruit) { | ||
case Fruit.Apple: | ||
console.log('an apple'); | ||
break; | ||
default: | ||
console.log('a fruit'); | ||
break; | ||
} | ||
``` | ||
<!--/tabs--> | ||
## Options | ||
### `requireDefaultForNonUnion` | ||
Examples of additional **incorrect** code for this rule with `{ requireDefaultForNonUnion: true }`: | ||
```ts option='{ "requireDefaultForNonUnion": true }' showPlaygroundButton | ||
const value: number = Math.floor(Math.random() * 3); | ||
switch (value) { | ||
case 0: | ||
return 0; | ||
case 1: | ||
return 1; | ||
} | ||
``` | ||
Since `value` is a non-union type it requires the switch case to have a default clause only with `requireDefaultForNonUnion` enabled. | ||
<!--/tabs--> | ||
## When Not To Use It | ||
If you don't frequently `switch` over union types with many parts, or intentionally wish to leave out some parts. | ||
If you don't frequently `switch` over union types or enums with many parts, or intentionally wish to leave out some parts, this rule may not be for you. |
@@ -53,5 +53,8 @@ --- | ||
## When To Use It | ||
## When Not To Use It | ||
If you want to ban use of one or all of the triple slash reference directives, or any time you might use triple-slash type reference directives and ES6 import declarations in the same file. | ||
Most modern TypeScript projects generally use `import` statements to bring in types. | ||
It's rare to need a `///` triple-slash reference outside of auto-generated code. | ||
If your project is a rare one with one of those use cases, this rule might not be for you. | ||
You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. | ||
@@ -58,0 +61,0 @@ ## When Not To Use It |
@@ -101,4 +101,6 @@ --- | ||
If your code intentionally waits to bind methods after use, such as by passing a `scope: this` along with the method, you can disable this rule. | ||
If your project dynamically changes `this` scopes around in a way TypeScript has difficulties modeling, this rule may not be viable to use. | ||
One likely difficult pattern is if your code intentionally waits to bind methods after use, such as by passing a `scope: this` along with the method. | ||
You might consider using [ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for those specific situations instead of completely disabling this rule. | ||
If you're wanting to use `toBeCalled` and similar matches in `jest` tests, you can disable this rule for your test files in favor of [`eslint-plugin-jest`'s version of this rule](https://github.com/jest-community/eslint-plugin-jest/blob/main/docs/rules/unbound-method.md). |
@@ -69,1 +69,10 @@ --- | ||
``` | ||
## When Not To Use It | ||
This is purely a stylistic rule to help with readability of function signature overloads. | ||
You can turn it off if you don't want to consistently keep them next to each other and unified. | ||
## Related To | ||
- [`adjacent-overload-signatures`](./adjacent-overload-signatures.md) |
@@ -1,2 +0,2 @@ | ||
import type { TSESLint } from '@typescript-eslint/utils'; | ||
import type { ClassicConfig } from '@typescript-eslint/utils/ts-eslint'; | ||
@@ -6,5 +6,5 @@ import type rules from './rules'; | ||
declare const cjsExport: { | ||
configs: Record<string, TSESLint.Linter.Config>; | ||
configs: Record<string, ClassicConfig.Config>; | ||
rules: typeof rules; | ||
}; | ||
export = cjsExport; |
{ | ||
"name": "@typescript-eslint/eslint-plugin", | ||
"version": "6.9.1", | ||
"version": "6.13.2", | ||
"description": "TypeScript plugin for ESLint", | ||
@@ -53,3 +53,3 @@ "files": [ | ||
"generate:configs": "yarn tsx tools/generate-configs.ts", | ||
"lint": "nx lint", | ||
"lint": "npx nx lint", | ||
"test": "jest --coverage --logHeapUsage", | ||
@@ -61,6 +61,6 @@ "test-single": "jest --no-coverage", | ||
"@eslint-community/regexpp": "^4.5.1", | ||
"@typescript-eslint/scope-manager": "6.9.1", | ||
"@typescript-eslint/type-utils": "6.9.1", | ||
"@typescript-eslint/utils": "6.9.1", | ||
"@typescript-eslint/visitor-keys": "6.9.1", | ||
"@typescript-eslint/scope-manager": "6.13.2", | ||
"@typescript-eslint/type-utils": "6.13.2", | ||
"@typescript-eslint/utils": "6.13.2", | ||
"@typescript-eslint/visitor-keys": "6.13.2", | ||
"debug": "^4.3.4", | ||
@@ -78,4 +78,4 @@ "graphemer": "^1.4.0", | ||
"@types/natural-compare": "*", | ||
"@typescript-eslint/rule-schema-to-typescript-types": "6.9.1", | ||
"@typescript-eslint/rule-tester": "6.9.1", | ||
"@typescript-eslint/rule-schema-to-typescript-types": "6.13.2", | ||
"@typescript-eslint/rule-tester": "6.13.2", | ||
"ajv": "^6.12.6", | ||
@@ -109,3 +109,3 @@ "chalk": "^5.3.0", | ||
}, | ||
"gitHead": "1e472949e561ea37e160f4c9d9e0136e04f40a1f" | ||
"gitHead": "cc2c6d3a4a515f7ccc23f10421a8db9c88345876" | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
2522281
505
30036
8
+ Added@typescript-eslint/scope-manager@6.13.2(transitive)
+ Added@typescript-eslint/type-utils@6.13.2(transitive)
+ Added@typescript-eslint/types@6.13.2(transitive)
+ Added@typescript-eslint/typescript-estree@6.13.2(transitive)
+ Added@typescript-eslint/utils@6.13.2(transitive)
+ Added@typescript-eslint/visitor-keys@6.13.2(transitive)
- Removed@typescript-eslint/scope-manager@6.9.1(transitive)
- Removed@typescript-eslint/type-utils@6.9.1(transitive)
- Removed@typescript-eslint/types@6.9.1(transitive)
- Removed@typescript-eslint/typescript-estree@6.9.1(transitive)
- Removed@typescript-eslint/utils@6.9.1(transitive)
- Removed@typescript-eslint/visitor-keys@6.9.1(transitive)