@typescript-eslint/eslint-plugin 8.67.0 → 8.68.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +5906 -0
- package/dist/configs/eslint-recommended-raw.js +1 -0
- package/dist/configs/eslintrc/all.js +1 -0
- package/dist/configs/eslintrc/base.js +1 -0
- package/dist/configs/eslintrc/disable-type-checked.js +1 -0
- package/dist/configs/eslintrc/eslint-recommended.js +1 -0
- package/dist/configs/eslintrc/recommended-type-checked-only.js +1 -0
- package/dist/configs/eslintrc/recommended-type-checked.js +1 -0
- package/dist/configs/eslintrc/recommended.js +1 -0
- package/dist/configs/eslintrc/strict-type-checked-only.js +1 -0
- package/dist/configs/eslintrc/strict-type-checked.js +1 -0
- package/dist/configs/eslintrc/strict.js +1 -0
- package/dist/configs/eslintrc/stylistic-type-checked-only.js +1 -0
- package/dist/configs/eslintrc/stylistic-type-checked.js +1 -0
- package/dist/configs/eslintrc/stylistic.js +1 -0
- package/dist/configs/flat/all.js +1 -0
- package/dist/configs/flat/base.js +1 -0
- package/dist/configs/flat/disable-type-checked.js +1 -0
- package/dist/configs/flat/eslint-recommended.js +1 -0
- package/dist/configs/flat/recommended-type-checked-only.js +1 -0
- package/dist/configs/flat/recommended-type-checked.js +1 -0
- package/dist/configs/flat/recommended.js +1 -0
- package/dist/configs/flat/strict-type-checked-only.js +1 -0
- package/dist/configs/flat/strict-type-checked.js +1 -0
- package/dist/configs/flat/strict.js +1 -0
- package/dist/configs/flat/stylistic-type-checked-only.js +1 -0
- package/dist/configs/flat/stylistic-type-checked.js +1 -0
- package/dist/configs/flat/stylistic.js +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -0
- package/dist/raw-plugin.d.ts +1 -1
- package/dist/raw-plugin.js +1 -0
- package/dist/rules/adjacent-overload-signatures.js +1 -0
- package/dist/rules/array-type.js +1 -0
- package/dist/rules/await-thenable.js +1 -0
- package/dist/rules/ban-ts-comment.js +1 -0
- package/dist/rules/ban-tslint-comment.js +1 -0
- package/dist/rules/class-literal-property-style.js +1 -0
- package/dist/rules/class-methods-use-this.js +1 -0
- package/dist/rules/consistent-generic-constructors.js +1 -0
- package/dist/rules/consistent-indexed-object-style.js +1 -0
- package/dist/rules/consistent-return.js +1 -0
- package/dist/rules/consistent-type-assertions.js +1 -0
- package/dist/rules/consistent-type-definitions.js +1 -0
- package/dist/rules/consistent-type-exports.js +1 -0
- package/dist/rules/consistent-type-imports.js +1 -0
- package/dist/rules/default-param-last.js +1 -0
- package/dist/rules/dot-notation.js +1 -0
- package/dist/rules/enum-utils/shared.d.ts +5 -0
- package/dist/rules/enum-utils/shared.js +68 -0
- package/dist/rules/explicit-function-return-type.js +1 -0
- package/dist/rules/explicit-member-accessibility.js +1 -0
- package/dist/rules/explicit-module-boundary-types.js +1 -0
- package/dist/rules/index.d.ts +1 -1
- package/dist/rules/index.js +1 -0
- package/dist/rules/init-declarations.js +1 -0
- package/dist/rules/max-params.js +1 -0
- package/dist/rules/member-ordering.js +1 -0
- package/dist/rules/method-signature-style.js +1 -0
- package/dist/rules/naming-convention-utils/enums.js +1 -0
- package/dist/rules/naming-convention-utils/format.js +1 -0
- package/dist/rules/naming-convention-utils/index.js +1 -0
- package/dist/rules/naming-convention-utils/parse-options.js +1 -0
- package/dist/rules/naming-convention-utils/schema.js +1 -0
- package/dist/rules/naming-convention-utils/shared.js +1 -0
- package/dist/rules/naming-convention-utils/types.js +1 -0
- package/dist/rules/naming-convention-utils/validator.js +1 -0
- package/dist/rules/naming-convention.js +1 -0
- package/dist/rules/no-array-constructor.js +1 -0
- package/dist/rules/no-array-delete.js +1 -0
- package/dist/rules/no-base-to-string.js +1 -0
- package/dist/rules/no-confusing-non-null-assertion.js +1 -0
- package/dist/rules/no-confusing-void-expression.js +8 -9
- package/dist/rules/no-deprecated.js +1 -0
- package/dist/rules/no-dupe-class-members.js +1 -0
- package/dist/rules/no-duplicate-enum-values.js +1 -0
- package/dist/rules/no-duplicate-type-constituents.js +1 -0
- package/dist/rules/no-dynamic-delete.js +1 -0
- package/dist/rules/no-empty-function.js +1 -0
- package/dist/rules/no-empty-interface.js +1 -0
- package/dist/rules/no-empty-object-type.js +9 -4
- package/dist/rules/no-explicit-any.js +1 -0
- package/dist/rules/no-extra-non-null-assertion.js +1 -0
- package/dist/rules/no-extraneous-class.js +1 -0
- package/dist/rules/no-floating-promises.js +64 -55
- package/dist/rules/no-for-in-array.js +1 -0
- package/dist/rules/no-implied-eval.js +1 -0
- package/dist/rules/no-import-type-side-effects.js +1 -0
- package/dist/rules/no-inferrable-types.js +1 -0
- package/dist/rules/no-invalid-this.js +1 -0
- package/dist/rules/no-invalid-void-type.js +1 -0
- package/dist/rules/no-loop-func.js +1 -0
- package/dist/rules/no-loss-of-precision.js +1 -0
- package/dist/rules/no-magic-numbers.js +1 -0
- package/dist/rules/no-meaningless-void-operator.js +1 -0
- package/dist/rules/no-misused-new.js +1 -0
- package/dist/rules/no-misused-promises.js +1 -0
- package/dist/rules/no-misused-spread.js +1 -0
- package/dist/rules/no-mixed-enums.js +1 -0
- package/dist/rules/no-namespace.js +1 -0
- package/dist/rules/no-non-null-asserted-nullish-coalescing.js +1 -0
- package/dist/rules/no-non-null-asserted-optional-chain.js +1 -0
- package/dist/rules/no-non-null-assertion.js +1 -0
- package/dist/rules/no-redeclare.js +1 -0
- package/dist/rules/no-redundant-type-constituents.js +1 -0
- package/dist/rules/no-require-imports.js +1 -0
- package/dist/rules/no-restricted-imports.js +1 -0
- package/dist/rules/no-restricted-types.js +1 -0
- package/dist/rules/no-shadow.js +1 -0
- package/dist/rules/no-this-alias.js +1 -0
- package/dist/rules/no-type-alias.js +1 -0
- package/dist/rules/no-unnecessary-boolean-literal-compare.js +1 -0
- package/dist/rules/no-unnecessary-condition.js +1 -0
- package/dist/rules/no-unnecessary-parameter-property-assignment.js +1 -0
- package/dist/rules/no-unnecessary-qualifier.js +1 -0
- package/dist/rules/no-unnecessary-template-expression.js +3 -14
- package/dist/rules/no-unnecessary-type-arguments.js +1 -0
- package/dist/rules/no-unnecessary-type-assertion.d.ts +1 -2
- package/dist/rules/no-unnecessary-type-assertion.js +14 -39
- package/dist/rules/no-unnecessary-type-constraint.js +1 -0
- package/dist/rules/no-unnecessary-type-conversion.js +1 -0
- package/dist/rules/no-unnecessary-type-parameters.js +1 -0
- package/dist/rules/no-unsafe-argument.js +2 -91
- package/dist/rules/no-unsafe-assignment.js +1 -0
- package/dist/rules/no-unsafe-call.js +1 -0
- package/dist/rules/no-unsafe-declaration-merging.js +1 -0
- package/dist/rules/no-unsafe-enum-comparison.js +3 -113
- package/dist/rules/no-unsafe-function-type.js +1 -0
- package/dist/rules/no-unsafe-member-access.js +1 -0
- package/dist/rules/no-unsafe-return.js +1 -0
- package/dist/rules/no-unsafe-type-assertion.js +1 -0
- package/dist/rules/no-unsafe-unary-minus.js +1 -0
- package/dist/rules/no-unused-expressions.js +1 -0
- package/dist/rules/no-unused-private-class-members.js +1 -0
- package/dist/rules/no-unused-vars.js +1 -0
- package/dist/rules/no-use-before-define.js +1 -0
- package/dist/rules/no-useless-constructor.js +1 -0
- package/dist/rules/no-useless-default-assignment.js +1 -0
- package/dist/rules/no-useless-empty-export.js +1 -0
- package/dist/rules/no-var-requires.js +1 -0
- package/dist/rules/no-wrapper-object-types.js +1 -0
- package/dist/rules/non-nullable-type-assertion-style.js +1 -0
- package/dist/rules/only-throw-error.js +1 -0
- package/dist/rules/parameter-properties.js +1 -0
- package/dist/rules/prefer-as-const.js +1 -0
- package/dist/rules/prefer-destructuring.js +1 -0
- package/dist/rules/prefer-enum-initializers.js +1 -0
- package/dist/rules/prefer-find.js +1 -0
- package/dist/rules/prefer-for-of.js +1 -0
- package/dist/rules/prefer-function-type.js +1 -0
- package/dist/rules/prefer-includes.js +1 -0
- package/dist/rules/prefer-literal-enum-member.js +1 -0
- package/dist/rules/prefer-namespace-keyword.js +1 -0
- package/dist/rules/prefer-nullish-coalescing.js +1 -0
- package/dist/rules/prefer-optional-chain-utils/PreferOptionalChainOptions.js +1 -0
- package/dist/rules/prefer-optional-chain-utils/analyzeChain.js +1 -0
- package/dist/rules/prefer-optional-chain-utils/checkNullishAndReport.js +1 -0
- package/dist/rules/prefer-optional-chain-utils/compareNodes.js +1 -0
- package/dist/rules/prefer-optional-chain-utils/gatherLogicalOperands.js +1 -0
- package/dist/rules/prefer-optional-chain.js +1 -0
- package/dist/rules/prefer-promise-reject-errors.js +1 -0
- package/dist/rules/prefer-readonly-parameter-types.js +1 -0
- package/dist/rules/prefer-readonly.js +1 -0
- package/dist/rules/prefer-reduce-type-parameter.js +1 -0
- package/dist/rules/prefer-regexp-exec.js +1 -0
- package/dist/rules/prefer-return-this-type.js +1 -0
- package/dist/rules/prefer-string-starts-ends-with.js +1 -0
- package/dist/rules/prefer-ts-expect-error.js +1 -0
- package/dist/rules/promise-function-async.js +1 -0
- package/dist/rules/related-getter-setter-pairs.js +1 -0
- package/dist/rules/require-array-sort-compare.js +1 -0
- package/dist/rules/require-await.js +1 -0
- package/dist/rules/restrict-plus-operands.js +1 -0
- package/dist/rules/restrict-template-expressions.js +1 -0
- package/dist/rules/return-await.js +13 -1
- package/dist/rules/sort-type-constituents.js +1 -0
- package/dist/rules/strict-boolean-expressions.js +1 -0
- package/dist/rules/strict-void-return.d.ts +3 -2
- package/dist/rules/strict-void-return.js +97 -5
- package/dist/rules/switch-exhaustiveness-check.js +1 -0
- package/dist/rules/triple-slash-reference.js +1 -0
- package/dist/rules/typedef.js +1 -0
- package/dist/rules/unbound-method.js +1 -0
- package/dist/rules/unified-signatures.d.ts +1 -1
- package/dist/rules/unified-signatures.js +73 -32
- package/dist/rules/use-unknown-in-catch-callback-variable.js +1 -0
- package/dist/util/FunctionSignature.d.ts +15 -0
- package/dist/util/FunctionSignature.js +123 -0
- package/dist/util/assertionFunctionUtils.js +1 -0
- package/dist/util/astUtils.js +1 -0
- package/dist/util/baseTypeUtils.d.ts +2 -0
- package/dist/util/baseTypeUtils.js +17 -0
- package/dist/util/class-scope-analyzer/classScopeAnalyzer.js +1 -0
- package/dist/util/class-scope-analyzer/extractComputedName.js +1 -0
- package/dist/util/class-scope-analyzer/types.js +1 -0
- package/dist/util/collectUnusedVariables.js +1 -0
- package/dist/util/createRule.js +1 -0
- package/dist/util/escapeRegExp.js +1 -0
- package/dist/util/explicitReturnTypeUtils.js +1 -0
- package/dist/util/getBaseTypesOfClassMember.js +1 -0
- package/dist/util/getConstraintInfo.js +1 -0
- package/dist/util/getESLintCoreRule.js +1 -0
- package/dist/util/getFixOrSuggest.js +1 -0
- package/dist/util/getForStatementHeadLoc.js +1 -0
- package/dist/util/getFunctionHeadLoc.js +1 -0
- package/dist/util/getMemberHeadLoc.js +1 -0
- package/dist/util/getOperatorPrecedence.js +1 -0
- package/dist/util/getParentFunctionNode.js +1 -0
- package/dist/util/getStaticStringValue.js +1 -0
- package/dist/util/getStringLength.js +1 -0
- package/dist/util/getTextWithParentheses.js +1 -0
- package/dist/util/getThisExpression.js +1 -0
- package/dist/util/getValueOfLiteralType.js +1 -0
- package/dist/util/getWrappedCode.js +1 -0
- package/dist/util/getWrappingFixer.js +1 -0
- package/dist/util/hasOverloadSignatures.js +1 -0
- package/dist/util/index.d.ts +2 -0
- package/dist/util/index.js +3 -0
- package/dist/util/isArrayMethodCallWithPredicate.js +1 -0
- package/dist/util/isAssignee.js +1 -0
- package/dist/util/isConditionalTest.js +1 -0
- package/dist/util/isHigherPrecedenceThanAwait.js +1 -0
- package/dist/util/isNodeEqual.js +1 -0
- package/dist/util/isNullLiteral.js +1 -0
- package/dist/util/isPromiseAggregatorMethod.js +1 -0
- package/dist/util/isStartOfArrowFunctionBody.d.ts +2 -0
- package/dist/util/isStartOfArrowFunctionBody.js +26 -0
- package/dist/util/isStartOfExpressionStatement.js +1 -0
- package/dist/util/isTypeImport.js +1 -0
- package/dist/util/isUndefinedIdentifier.js +1 -0
- package/dist/util/misc.js +1 -0
- package/dist/util/needsPrecedingSemiColon.js +1 -0
- package/dist/util/needsToBeAwaited.js +1 -0
- package/dist/util/objectIterators.js +1 -0
- package/dist/util/promiseUtils.js +1 -0
- package/dist/util/rangeToLoc.js +1 -0
- package/dist/util/referenceContainsTypePredicate.js +1 -0
- package/dist/util/referenceContainsTypeQuery.js +1 -0
- package/dist/util/scopeUtils.js +1 -0
- package/dist/util/skipChainExpression.js +1 -0
- package/dist/util/truthinessUtils.js +1 -0
- package/dist/util/types.js +1 -0
- package/dist/util/walkStatements.js +1 -0
- package/package.json +12 -11
|
@@ -45,10 +45,13 @@ exports.default = util.createRule({
|
|
|
45
45
|
description: 'Disallow passing a value-returning function in a position accepting a void function',
|
|
46
46
|
requiresTypeChecking: true,
|
|
47
47
|
},
|
|
48
|
+
hasSuggestions: true,
|
|
48
49
|
messages: {
|
|
49
50
|
asyncFunc: 'Async function used in a context where a void function is expected.',
|
|
50
51
|
nonVoidFunc: 'Value-returning function used in a context where a void function is expected.',
|
|
51
52
|
nonVoidReturn: 'Value returned in a context where a void return is expected.',
|
|
53
|
+
suggestAddVoidOp: 'Add a void operator to discard the return value.',
|
|
54
|
+
suggestWrapInAsyncIIFE: 'Wrap the function body in an async IIFE.',
|
|
52
55
|
},
|
|
53
56
|
schema: [
|
|
54
57
|
{
|
|
@@ -324,20 +327,55 @@ exports.default = util.createRule({
|
|
|
324
327
|
}
|
|
325
328
|
if (funcNode.async) {
|
|
326
329
|
// The provided function is an async function.
|
|
327
|
-
|
|
330
|
+
if (funcNode.body.type !== utils_1.AST_NODE_TYPES.BlockStatement) {
|
|
331
|
+
// This async function is an arrow function shorthand without braces.
|
|
332
|
+
return context.report({
|
|
333
|
+
loc: util.getFunctionHeadLoc(funcNode, sourceCode),
|
|
334
|
+
messageId: 'asyncFunc',
|
|
335
|
+
suggest: utils_1.ASTUtils.hasSideEffect(funcNode.body, sourceCode)
|
|
336
|
+
? // This function has side effects, e.g. `async () => doSomething()`.
|
|
337
|
+
// Suggest removing the async keyword and adding a void operator.
|
|
338
|
+
[
|
|
339
|
+
{
|
|
340
|
+
messageId: 'suggestAddVoidOp',
|
|
341
|
+
fix: fixer => addVoidToArrowFix(fixer, funcNode),
|
|
342
|
+
},
|
|
343
|
+
]
|
|
344
|
+
: [],
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
// This async function has a block body.
|
|
348
|
+
// Suggest wrapping its body in an async IIFE.
|
|
328
349
|
return context.report({
|
|
329
350
|
loc: util.getFunctionHeadLoc(funcNode, sourceCode),
|
|
330
|
-
messageId:
|
|
351
|
+
messageId: 'asyncFunc',
|
|
352
|
+
suggest: [
|
|
353
|
+
{
|
|
354
|
+
messageId: 'suggestWrapInAsyncIIFE',
|
|
355
|
+
fix: fixer => wrapInAsyncIIFEFix(fixer, funcNode),
|
|
356
|
+
},
|
|
357
|
+
],
|
|
331
358
|
});
|
|
332
359
|
}
|
|
360
|
+
// This function is a regular or arrow sync function.
|
|
333
361
|
if (funcNode.body.type !== utils_1.AST_NODE_TYPES.BlockStatement) {
|
|
334
|
-
//
|
|
362
|
+
// This function is an arrow function shorthand without braces.
|
|
335
363
|
return context.report({
|
|
336
364
|
node: funcNode.body,
|
|
337
|
-
messageId:
|
|
365
|
+
messageId: 'nonVoidReturn',
|
|
366
|
+
suggest: utils_1.ASTUtils.hasSideEffect(funcNode.body, sourceCode)
|
|
367
|
+
? // This function has side effects, e.g. `() => doSomething()`.
|
|
368
|
+
// Suggest adding a void operator.
|
|
369
|
+
[
|
|
370
|
+
{
|
|
371
|
+
messageId: 'suggestAddVoidOp',
|
|
372
|
+
fix: fixer => addVoidToArrowFix(fixer, funcNode),
|
|
373
|
+
},
|
|
374
|
+
]
|
|
375
|
+
: [],
|
|
338
376
|
});
|
|
339
377
|
}
|
|
340
|
-
//
|
|
378
|
+
// This function is a regular or arrow sync function with a block body.
|
|
341
379
|
// Check return type annotation.
|
|
342
380
|
if (funcNode.returnType != null) {
|
|
343
381
|
// The provided function has an explicit return type annotation.
|
|
@@ -373,5 +411,59 @@ exports.default = util.createRule({
|
|
|
373
411
|
}
|
|
374
412
|
// No invalid returns found. The function is allowed.
|
|
375
413
|
}
|
|
414
|
+
/**
|
|
415
|
+
* Removes the async keyword and replaces the return type with void.
|
|
416
|
+
*/
|
|
417
|
+
function* makeSyncFuncFix(fixer, funcNode) {
|
|
418
|
+
if (funcNode.async) {
|
|
419
|
+
// Remove async keyword
|
|
420
|
+
const funcHeadNode = funcNode.parent.type === utils_1.AST_NODE_TYPES.Property ||
|
|
421
|
+
funcNode.parent.type === utils_1.AST_NODE_TYPES.MethodDefinition
|
|
422
|
+
? funcNode.parent
|
|
423
|
+
: funcNode;
|
|
424
|
+
const asyncToken = util.nullThrows(sourceCode.getFirstToken(funcHeadNode, {
|
|
425
|
+
filter: token => token.value === 'async',
|
|
426
|
+
}), util.NullThrowsReasons.MissingToken('async keyword', funcNode.type));
|
|
427
|
+
yield fixer.remove(asyncToken);
|
|
428
|
+
}
|
|
429
|
+
// Replace return type with void
|
|
430
|
+
if (funcNode.returnType != null) {
|
|
431
|
+
yield fixer.replaceText(funcNode.returnType.typeAnnotation, 'void');
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
/**
|
|
435
|
+
* Makes the function sync and adds a void operator to the arrow shorthand body.
|
|
436
|
+
*/
|
|
437
|
+
function* addVoidToArrowFix(fixer, funcNode) {
|
|
438
|
+
yield* makeSyncFuncFix(fixer, funcNode);
|
|
439
|
+
// Add void operator
|
|
440
|
+
yield util.getWrappingFixer({
|
|
441
|
+
node: funcNode.body,
|
|
442
|
+
sourceCode,
|
|
443
|
+
wrap: code => `void ${code}`,
|
|
444
|
+
})(fixer);
|
|
445
|
+
}
|
|
446
|
+
/**
|
|
447
|
+
* Makes the function sync and wraps the body in an inner async IIFE.
|
|
448
|
+
*/
|
|
449
|
+
function* wrapInAsyncIIFEFix(fixer, funcNode) {
|
|
450
|
+
yield* makeSyncFuncFix(fixer, funcNode);
|
|
451
|
+
// Wrap body in async IIFE.
|
|
452
|
+
// This preserves the node kind (normal/arrow) for the _outer_ function
|
|
453
|
+
// and uses an arrow function for the _inner_ function,
|
|
454
|
+
// so that `this` will always refer to the same value as before.
|
|
455
|
+
if (funcNode.type === utils_1.AST_NODE_TYPES.ArrowFunctionExpression) {
|
|
456
|
+
const arrowToken = util.nullThrows(sourceCode.getTokenBefore(funcNode.body, {
|
|
457
|
+
filter: token => token.value === '=>',
|
|
458
|
+
}), util.NullThrowsReasons.MissingToken('arrow token', 'before arrow function body'));
|
|
459
|
+
yield fixer.insertTextAfter(arrowToken, ' void (async () =>');
|
|
460
|
+
yield fixer.insertTextAfter(funcNode, ')()');
|
|
461
|
+
}
|
|
462
|
+
else {
|
|
463
|
+
yield fixer.insertTextBefore(funcNode.body, '{ (async () => ');
|
|
464
|
+
yield fixer.insertTextAfter(funcNode.body, ')(); }');
|
|
465
|
+
}
|
|
466
|
+
}
|
|
376
467
|
},
|
|
377
468
|
});
|
|
469
|
+
//# sourceMappingURL=strict-void-return.js.map
|
package/dist/rules/typedef.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type MessageIds = 'omittingRestParameter' | 'omittingSingleParameter' | 'singleParameterDifference';
|
|
1
|
+
export type MessageIds = 'allParametersAreSame' | 'omittingRestParameter' | 'omittingSingleParameter' | 'singleParameterDifference';
|
|
2
2
|
export type Options = [
|
|
3
3
|
{
|
|
4
4
|
ignoreDifferentlyNamedParameters?: boolean;
|
|
@@ -12,9 +12,10 @@ exports.default = (0, util_1.createRule)({
|
|
|
12
12
|
recommended: 'strict',
|
|
13
13
|
},
|
|
14
14
|
messages: {
|
|
15
|
+
allParametersAreSame: '{{failureStringStart}} with identical parameters.',
|
|
15
16
|
omittingRestParameter: '{{failureStringStart}} with a rest parameter.',
|
|
16
17
|
omittingSingleParameter: '{{failureStringStart}} with an optional parameter.',
|
|
17
|
-
singleParameterDifference: '{{failureStringStart}} taking `{{
|
|
18
|
+
singleParameterDifference: '{{failureStringStart}} taking `{{types}}`.',
|
|
18
19
|
},
|
|
19
20
|
schema: [
|
|
20
21
|
{
|
|
@@ -57,20 +58,15 @@ exports.default = (0, util_1.createRule)({
|
|
|
57
58
|
case 'single-parameter-difference': {
|
|
58
59
|
const { p0, p1 } = unify;
|
|
59
60
|
const lineOfOtherOverload = only2 ? undefined : p0.loc.start.line;
|
|
60
|
-
const typeAnnotation0 =
|
|
61
|
-
|
|
62
|
-
: p0.typeAnnotation;
|
|
63
|
-
const typeAnnotation1 = isTSParameterProperty(p1)
|
|
64
|
-
? p1.parameter.typeAnnotation
|
|
65
|
-
: p1.typeAnnotation;
|
|
61
|
+
const typeAnnotation0 = getParameterTypeAnnotation(p0);
|
|
62
|
+
const typeAnnotation1 = getParameterTypeAnnotation(p1);
|
|
66
63
|
context.report({
|
|
67
64
|
loc: p1.loc,
|
|
68
65
|
node: p1,
|
|
69
66
|
messageId: 'singleParameterDifference',
|
|
70
67
|
data: {
|
|
71
68
|
failureStringStart: failureStringStart(lineOfOtherOverload),
|
|
72
|
-
|
|
73
|
-
type2: context.sourceCode.getText(typeAnnotation1?.typeAnnotation),
|
|
69
|
+
types: getUnifiedTypeText(typeAnnotation0, typeAnnotation1),
|
|
74
70
|
},
|
|
75
71
|
});
|
|
76
72
|
break;
|
|
@@ -90,7 +86,24 @@ exports.default = (0, util_1.createRule)({
|
|
|
90
86
|
failureStringStart: failureStringStart(lineOfOtherOverload),
|
|
91
87
|
},
|
|
92
88
|
});
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
case 'all-parameters-are-same': {
|
|
92
|
+
const { signature0, signature1 } = unify;
|
|
93
|
+
const lineOfOtherOverload = only2
|
|
94
|
+
? undefined
|
|
95
|
+
: signature0.loc.start.line;
|
|
96
|
+
context.report({
|
|
97
|
+
node: signature1,
|
|
98
|
+
messageId: 'allParametersAreSame',
|
|
99
|
+
data: {
|
|
100
|
+
failureStringStart: failureStringStart(lineOfOtherOverload),
|
|
101
|
+
},
|
|
102
|
+
});
|
|
103
|
+
break;
|
|
93
104
|
}
|
|
105
|
+
default:
|
|
106
|
+
unify;
|
|
94
107
|
}
|
|
95
108
|
}
|
|
96
109
|
}
|
|
@@ -114,7 +127,7 @@ exports.default = (0, util_1.createRule)({
|
|
|
114
127
|
return undefined;
|
|
115
128
|
}
|
|
116
129
|
return a.params.length === b.params.length
|
|
117
|
-
?
|
|
130
|
+
? signaturesHaveSameAmountOfParameters(a, b)
|
|
118
131
|
: signaturesDifferByOptionalOrRestParameter(a, b);
|
|
119
132
|
}
|
|
120
133
|
function signaturesCanBeUnified(a, b, isTypeParameter) {
|
|
@@ -138,15 +151,20 @@ exports.default = (0, util_1.createRule)({
|
|
|
138
151
|
return false;
|
|
139
152
|
}
|
|
140
153
|
}
|
|
141
|
-
return (typesAreEqual(a.returnType, b.returnType) &&
|
|
154
|
+
return (typesAreEqual(a.returnType?.typeAnnotation, b.returnType?.typeAnnotation) &&
|
|
142
155
|
// Must take the same type parameters.
|
|
143
156
|
// If one uses a type parameter (from outside) and the other doesn't, they shouldn't be joined.
|
|
144
157
|
(0, util_1.arraysAreEqual)(aTypeParams, bTypeParams, typeParametersAreEqual) &&
|
|
145
158
|
signatureUsesTypeParameter(a, isTypeParameter) ===
|
|
146
159
|
signatureUsesTypeParameter(b, isTypeParameter));
|
|
147
160
|
}
|
|
148
|
-
/**
|
|
149
|
-
|
|
161
|
+
/**
|
|
162
|
+
* Detect no difference, i.e. `a(x: number, y: string)` and `a(x: number, y: string)`,
|
|
163
|
+
* or one param difference, i.e. `a(x: number, y: number, z: number)` and `a(x: number, y: string, z: number)`.
|
|
164
|
+
*/
|
|
165
|
+
function signaturesHaveSameAmountOfParameters(signature0, signature1) {
|
|
166
|
+
const types1 = signature0.params;
|
|
167
|
+
const types2 = signature1.params;
|
|
150
168
|
const firstParam1 = types1[0];
|
|
151
169
|
const firstParam2 = types2[0];
|
|
152
170
|
// exempt signatures with `this: void` from the rule
|
|
@@ -155,7 +173,11 @@ exports.default = (0, util_1.createRule)({
|
|
|
155
173
|
}
|
|
156
174
|
const index = getIndexOfFirstDifference(types1, types2, parametersAreEqual);
|
|
157
175
|
if (index == null) {
|
|
158
|
-
return
|
|
176
|
+
return {
|
|
177
|
+
kind: 'all-parameters-are-same',
|
|
178
|
+
signature0,
|
|
179
|
+
signature1,
|
|
180
|
+
};
|
|
159
181
|
}
|
|
160
182
|
// If remaining arrays are equal, the signatures differ by just one parameter type
|
|
161
183
|
if (!(0, util_1.arraysAreEqual)(types1.slice(index + 1), types2.slice(index + 1), parametersAreEqual)) {
|
|
@@ -170,6 +192,39 @@ exports.default = (0, util_1.createRule)({
|
|
|
170
192
|
? { kind: 'single-parameter-difference', p0: a, p1: b }
|
|
171
193
|
: undefined;
|
|
172
194
|
}
|
|
195
|
+
function getParameterTypeAnnotation(parameter) {
|
|
196
|
+
return isTSParameterProperty(parameter)
|
|
197
|
+
? parameter.parameter.typeAnnotation?.typeAnnotation
|
|
198
|
+
: parameter.typeAnnotation?.typeAnnotation;
|
|
199
|
+
}
|
|
200
|
+
function getUnifiedTypeText(type0, type1) {
|
|
201
|
+
// When a signature's parameter has no type annotation
|
|
202
|
+
if (type0 == null || type1 == null) {
|
|
203
|
+
return getUnionMemberText((0, util_1.nullThrows)(type0 ?? type1, 'Expected a type annotation for one of the parameters, but both were undefined'));
|
|
204
|
+
}
|
|
205
|
+
const members = [...getUnionMembers(type0), ...getUnionMembers(type1)];
|
|
206
|
+
const uniqueMembers = [];
|
|
207
|
+
for (const member of members) {
|
|
208
|
+
if (!uniqueMembers.some(other => typesAreEqual(other, member))) {
|
|
209
|
+
uniqueMembers.push(member);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
return uniqueMembers
|
|
213
|
+
.map(member => getUnionMemberText(member))
|
|
214
|
+
.join(' | ');
|
|
215
|
+
}
|
|
216
|
+
function getUnionMembers(type) {
|
|
217
|
+
return type.type === utils_1.AST_NODE_TYPES.TSUnionType
|
|
218
|
+
? type.types.flatMap(getUnionMembers)
|
|
219
|
+
: [type];
|
|
220
|
+
}
|
|
221
|
+
function getUnionMemberText(type) {
|
|
222
|
+
const text = context.sourceCode.getText(type);
|
|
223
|
+
const needsParentheses = type.type === utils_1.AST_NODE_TYPES.TSConditionalType ||
|
|
224
|
+
type.type === utils_1.AST_NODE_TYPES.TSConstructorType ||
|
|
225
|
+
type.type === utils_1.AST_NODE_TYPES.TSFunctionType;
|
|
226
|
+
return needsParentheses ? `(${text})` : text;
|
|
227
|
+
}
|
|
173
228
|
function isThisParam(param) {
|
|
174
229
|
return param?.type === utils_1.AST_NODE_TYPES.Identifier && param.name === 'this';
|
|
175
230
|
}
|
|
@@ -209,15 +264,7 @@ exports.default = (0, util_1.createRule)({
|
|
|
209
264
|
}
|
|
210
265
|
}
|
|
211
266
|
for (let i = 0; i < minLength; i++) {
|
|
212
|
-
|
|
213
|
-
const sig2i = sig2[i];
|
|
214
|
-
const typeAnnotation1 = isTSParameterProperty(sig1i)
|
|
215
|
-
? sig1i.parameter.typeAnnotation
|
|
216
|
-
: sig1i.typeAnnotation;
|
|
217
|
-
const typeAnnotation2 = isTSParameterProperty(sig2i)
|
|
218
|
-
? sig2i.parameter.typeAnnotation
|
|
219
|
-
: sig2i.typeAnnotation;
|
|
220
|
-
if (!typesAreEqual(typeAnnotation1, typeAnnotation2)) {
|
|
267
|
+
if (!typesAreEqual(getParameterTypeAnnotation(sig1[i]), getParameterTypeAnnotation(sig2[i]))) {
|
|
221
268
|
return undefined;
|
|
222
269
|
}
|
|
223
270
|
}
|
|
@@ -265,14 +312,8 @@ exports.default = (0, util_1.createRule)({
|
|
|
265
312
|
return node.type === utils_1.AST_NODE_TYPES.TSParameterProperty;
|
|
266
313
|
}
|
|
267
314
|
function parametersAreEqual(a, b) {
|
|
268
|
-
const typeAnnotationA = isTSParameterProperty(a)
|
|
269
|
-
? a.parameter.typeAnnotation
|
|
270
|
-
: a.typeAnnotation;
|
|
271
|
-
const typeAnnotationB = isTSParameterProperty(b)
|
|
272
|
-
? b.parameter.typeAnnotation
|
|
273
|
-
: b.typeAnnotation;
|
|
274
315
|
return (parametersHaveEqualSigils(a, b) &&
|
|
275
|
-
typesAreEqual(
|
|
316
|
+
typesAreEqual(getParameterTypeAnnotation(a), getParameterTypeAnnotation(b)));
|
|
276
317
|
}
|
|
277
318
|
/** True for optional/rest parameters. */
|
|
278
319
|
function parameterMayBeMissing(p) {
|
|
@@ -300,8 +341,7 @@ exports.default = (0, util_1.createRule)({
|
|
|
300
341
|
return (a === b ||
|
|
301
342
|
(a != null &&
|
|
302
343
|
b != null &&
|
|
303
|
-
context.sourceCode.getText(a
|
|
304
|
-
context.sourceCode.getText(b.typeAnnotation)));
|
|
344
|
+
context.sourceCode.getText(a) === context.sourceCode.getText(b)));
|
|
305
345
|
}
|
|
306
346
|
function constraintsAreEqual(a, b) {
|
|
307
347
|
return a === b || (a != null && a.type === b?.type);
|
|
@@ -463,3 +503,4 @@ function isPrivateIdentifier(node) {
|
|
|
463
503
|
function isGetterOrSetter(node) {
|
|
464
504
|
return node.kind === 'get' || node.kind === 'set';
|
|
465
505
|
}
|
|
506
|
+
//# sourceMappingURL=unified-signatures.js.map
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import * as ts from 'typescript';
|
|
2
|
+
/**
|
|
3
|
+
* Tracks checking the parameters of a single function signature.
|
|
4
|
+
* This allows rules to "consume" parameters and check for unsafe comparisons.
|
|
5
|
+
*/
|
|
6
|
+
export declare class FunctionSignature {
|
|
7
|
+
private readonly paramTypes;
|
|
8
|
+
private readonly restType;
|
|
9
|
+
private hasConsumedArguments;
|
|
10
|
+
private parameterTypeIndex;
|
|
11
|
+
private constructor();
|
|
12
|
+
static create(checker: ts.TypeChecker, tsNode: ts.CallLikeExpression): FunctionSignature;
|
|
13
|
+
consumeRemainingArguments(): void;
|
|
14
|
+
getNextParameterType(): ts.Type | null;
|
|
15
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.FunctionSignature = void 0;
|
|
37
|
+
const utils_1 = require("@typescript-eslint/utils");
|
|
38
|
+
const ts = __importStar(require("typescript"));
|
|
39
|
+
const misc_1 = require("./misc");
|
|
40
|
+
const { nullThrows } = utils_1.ESLintUtils;
|
|
41
|
+
var RestTypeKind;
|
|
42
|
+
(function (RestTypeKind) {
|
|
43
|
+
RestTypeKind[RestTypeKind["Array"] = 0] = "Array";
|
|
44
|
+
RestTypeKind[RestTypeKind["Other"] = 1] = "Other";
|
|
45
|
+
RestTypeKind[RestTypeKind["Tuple"] = 2] = "Tuple";
|
|
46
|
+
})(RestTypeKind || (RestTypeKind = {}));
|
|
47
|
+
/**
|
|
48
|
+
* Tracks checking the parameters of a single function signature.
|
|
49
|
+
* This allows rules to "consume" parameters and check for unsafe comparisons.
|
|
50
|
+
*/
|
|
51
|
+
class FunctionSignature {
|
|
52
|
+
paramTypes;
|
|
53
|
+
restType;
|
|
54
|
+
hasConsumedArguments = false;
|
|
55
|
+
parameterTypeIndex = 0;
|
|
56
|
+
constructor(paramTypes, restType) {
|
|
57
|
+
this.paramTypes = paramTypes;
|
|
58
|
+
this.restType = restType;
|
|
59
|
+
}
|
|
60
|
+
static create(checker, tsNode) {
|
|
61
|
+
// getResolvedSignature only returns undefined for nodes outside the parse
|
|
62
|
+
// tree, and tsNode always comes from the AST node map.
|
|
63
|
+
const signature = nullThrows(checker.getResolvedSignature(tsNode), 'Expected the call-like node to resolve to a signature.');
|
|
64
|
+
const paramTypes = [];
|
|
65
|
+
let restType = null;
|
|
66
|
+
const parameters = signature.getParameters();
|
|
67
|
+
for (let index = 0; index < parameters.length; index += 1) {
|
|
68
|
+
const param = parameters[index];
|
|
69
|
+
const declaration = param.getDeclarations()?.[0];
|
|
70
|
+
const type = checker.getTypeOfSymbolAtLocation(param, tsNode);
|
|
71
|
+
const constrainedType = checker.getBaseConstraintOfType(type) ?? type;
|
|
72
|
+
if (declaration && (0, misc_1.isRestParameterDeclaration)(declaration)) {
|
|
73
|
+
if (checker.isTupleType(constrainedType)) {
|
|
74
|
+
restType = {
|
|
75
|
+
index,
|
|
76
|
+
kind: RestTypeKind.Tuple,
|
|
77
|
+
typeArguments: checker.getTypeArguments(constrainedType),
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
const elementType = checker.getIndexTypeOfType(constrainedType, ts.IndexKind.Number);
|
|
82
|
+
restType = elementType
|
|
83
|
+
? { index, kind: RestTypeKind.Array, type: elementType }
|
|
84
|
+
: { index, kind: RestTypeKind.Other, type: constrainedType };
|
|
85
|
+
}
|
|
86
|
+
break;
|
|
87
|
+
}
|
|
88
|
+
paramTypes.push(type);
|
|
89
|
+
}
|
|
90
|
+
return new FunctionSignature(paramTypes, restType);
|
|
91
|
+
}
|
|
92
|
+
consumeRemainingArguments() {
|
|
93
|
+
this.hasConsumedArguments = true;
|
|
94
|
+
}
|
|
95
|
+
getNextParameterType() {
|
|
96
|
+
const index = this.parameterTypeIndex;
|
|
97
|
+
this.parameterTypeIndex += 1;
|
|
98
|
+
if (index >= this.paramTypes.length || this.hasConsumedArguments) {
|
|
99
|
+
if (this.restType == null) {
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
switch (this.restType.kind) {
|
|
103
|
+
case RestTypeKind.Tuple: {
|
|
104
|
+
const { typeArguments } = this.restType;
|
|
105
|
+
if (this.hasConsumedArguments) {
|
|
106
|
+
return typeArguments[typeArguments.length - 1];
|
|
107
|
+
}
|
|
108
|
+
const typeIndex = index - this.restType.index;
|
|
109
|
+
if (typeIndex >= typeArguments.length) {
|
|
110
|
+
return typeArguments[typeArguments.length - 1];
|
|
111
|
+
}
|
|
112
|
+
return typeArguments[typeIndex];
|
|
113
|
+
}
|
|
114
|
+
case RestTypeKind.Array:
|
|
115
|
+
case RestTypeKind.Other:
|
|
116
|
+
return this.restType.type;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return this.paramTypes[index];
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
exports.FunctionSignature = FunctionSignature;
|
|
123
|
+
//# sourceMappingURL=FunctionSignature.js.map
|
package/dist/util/astUtils.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { ParserServicesWithTypeInformation } from '@typescript-eslint/utils';
|
|
2
2
|
import type { InterfaceType, Type } from 'typescript';
|
|
3
3
|
export declare function hasBaseTypes(type: Type): type is InterfaceType;
|
|
4
|
+
export declare function isNumberLike(type: Type): boolean;
|
|
5
|
+
export declare function isStringLike(type: Type): boolean;
|
|
4
6
|
/**
|
|
5
7
|
* Recursively checks if a type or any of its base types matches the provided
|
|
6
8
|
* matcher function.
|
|
@@ -34,6 +34,8 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.hasBaseTypes = hasBaseTypes;
|
|
37
|
+
exports.isNumberLike = isNumberLike;
|
|
38
|
+
exports.isStringLike = isStringLike;
|
|
37
39
|
exports.matchesTypeOrBaseType = matchesTypeOrBaseType;
|
|
38
40
|
const ts_api_utils_1 = require("ts-api-utils");
|
|
39
41
|
const tsutils = __importStar(require("ts-api-utils"));
|
|
@@ -53,6 +55,20 @@ function hasBaseTypes(type) {
|
|
|
53
55
|
return ((0, ts_api_utils_1.isObjectType)(type) &&
|
|
54
56
|
(0, ts_api_utils_1.isObjectFlagSet)(type, ts.ObjectFlags.Interface | ts.ObjectFlags.Class));
|
|
55
57
|
}
|
|
58
|
+
function isNumberLike(type) {
|
|
59
|
+
return tsutils
|
|
60
|
+
.unionConstituents(type)
|
|
61
|
+
.every(unionPart => tsutils
|
|
62
|
+
.intersectionConstituents(unionPart)
|
|
63
|
+
.some(intersectionPart => tsutils.isTypeFlagSet(intersectionPart, ts.TypeFlags.NumberLike)));
|
|
64
|
+
}
|
|
65
|
+
function isStringLike(type) {
|
|
66
|
+
return tsutils
|
|
67
|
+
.unionConstituents(type)
|
|
68
|
+
.every(unionPart => tsutils
|
|
69
|
+
.intersectionConstituents(unionPart)
|
|
70
|
+
.some(intersectionPart => tsutils.isTypeFlagSet(intersectionPart, ts.TypeFlags.StringLike)));
|
|
71
|
+
}
|
|
56
72
|
/**
|
|
57
73
|
* Recursively checks if a type or any of its base types matches the provided
|
|
58
74
|
* matcher function.
|
|
@@ -73,3 +89,4 @@ function matchesTypeOrBaseType(services, matcher, type, seen = new Set()) {
|
|
|
73
89
|
const checker = services.program.getTypeChecker();
|
|
74
90
|
return getBaseTypesForType(checker, type).some(base => matchesTypeOrBaseType(services, matcher, base, seen));
|
|
75
91
|
}
|
|
92
|
+
//# sourceMappingURL=baseTypeUtils.js.map
|
|
@@ -599,3 +599,4 @@ function isUsedVariable(variable) {
|
|
|
599
599
|
function collectVariables(context) {
|
|
600
600
|
return UnusedVarsVisitor.collectUnusedVariables(context.sourceCode.ast, utils_1.ESLintUtils.nullThrows(context.sourceCode.scopeManager, 'Missing required scope manager'));
|
|
601
601
|
}
|
|
602
|
+
//# sourceMappingURL=collectUnusedVariables.js.map
|
package/dist/util/createRule.js
CHANGED
|
@@ -3,3 +3,4 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.createRule = void 0;
|
|
4
4
|
const utils_1 = require("@typescript-eslint/utils");
|
|
5
5
|
exports.createRule = utils_1.ESLintUtils.RuleCreator(name => `https://typescript-eslint.io/rules/${name}`);
|
|
6
|
+
//# sourceMappingURL=createRule.js.map
|