@typescript-eslint/eslint-plugin 8.70.1-alpha.1 → 8.70.1-alpha.11

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.
@@ -155,6 +155,14 @@ exports.default = (0, util_1.createRule)({
155
155
  return fixer.replaceText(node.parent, 'PropertyKey');
156
156
  };
157
157
  }
158
+ function createUnknownFixer(node) {
159
+ return (fixer) => {
160
+ return fixer.replaceText(node, node.parent.type === utils_1.AST_NODE_TYPES.TSTypeAnnotation &&
161
+ isNodeRestElementInFunction(node.parent.parent)
162
+ ? 'unknown[]'
163
+ : 'unknown');
164
+ };
165
+ }
158
166
  return {
159
167
  TSAnyKeyword(node) {
160
168
  const isKeyofAny = isNodeWithinKeyofAny(node);
@@ -173,7 +181,7 @@ exports.default = (0, util_1.createRule)({
173
181
  : [
174
182
  {
175
183
  messageId: 'suggestUnknown',
176
- fix: fixer => fixer.replaceText(node, 'unknown'),
184
+ fix: createUnknownFixer(node),
177
185
  },
178
186
  {
179
187
  messageId: 'suggestNever',
@@ -184,7 +192,7 @@ exports.default = (0, util_1.createRule)({
184
192
  if (fixToUnknown) {
185
193
  fixOrSuggest.fix = isKeyofAny
186
194
  ? createPropertyKeyFixer(node)
187
- : fixer => fixer.replaceText(node, 'unknown');
195
+ : createUnknownFixer(node);
188
196
  }
189
197
  context.report({
190
198
  node,
@@ -63,8 +63,12 @@ exports.default = (0, util_1.createRule)({
63
63
  type.getCallSignatures().length === 0 &&
64
64
  type.getConstructSignatures().length === 0 &&
65
65
  // Types still awaiting type arguments, such as `Record<T, unknown>`
66
- // inside a generic declaration, also have no members yet.
67
- checker.isTypeAssignableTo(checker.getNumberType(), type));
66
+ // inside a generic declaration, also have no members yet. Every
67
+ // primitive is assignable to `{}`, so probing with more than one of
68
+ // them rules those out: a mapped type whose keys are not resolved yet,
69
+ // such as `{ [K in Keys<T>]: K }`, accepts `number` but not `string`.
70
+ checker.isTypeAssignableTo(checker.getNumberType(), type) &&
71
+ checker.isTypeAssignableTo(checker.getStringType(), type));
68
72
  }
69
73
  function containsEmptyObjectType(type) {
70
74
  return (isEmptyObjectType(type) ||
@@ -84,6 +84,11 @@ exports.default = (0, util_1.createRule)({
84
84
  if (inner.type === utils_1.AST_NODE_TYPES.Literal && inner.value === 0) {
85
85
  return;
86
86
  }
87
+ // `void (x = value)` discards the assignment result so the
88
+ // expression evaluates to undefined (e.g. `() => void (x = 1)`).
89
+ if (inner.type === utils_1.AST_NODE_TYPES.AssignmentExpression) {
90
+ return;
91
+ }
87
92
  const tsArgument = services.esTreeNodeToTSNodeMap.get(node.argument);
88
93
  const argType = services.getTypeAtLocation(node.argument);
89
94
  // Allow `void promiseValue` so this rule does not fight no-floating-promises.
@@ -98,7 +98,7 @@ exports.default = (0, util_1.createRule)({
98
98
  }
99
99
  function getMapSpreadSuggestions(node, type) {
100
100
  const types = tsutils.unionConstituents(type);
101
- if (types.some(t => !isMap(services.program, t))) {
101
+ if (types.some(t => !isIterableMap(services.program, t))) {
102
102
  return null;
103
103
  }
104
104
  if (node.parent.type === utils_1.AST_NODE_TYPES.ObjectExpression &&
@@ -252,6 +252,9 @@ function isClassDeclaration(type) {
252
252
  function isMap(program, type) {
253
253
  return isTypeRecurser(type, t => (0, util_1.isBuiltinSymbolLike)(program, t, ['Map', 'ReadonlyMap', 'WeakMap']));
254
254
  }
255
+ function isIterableMap(program, type) {
256
+ return isTypeRecurser(type, t => (0, util_1.isBuiltinSymbolLike)(program, t, ['Map', 'ReadonlyMap']));
257
+ }
255
258
  function isTypeRecurser(type, predicate) {
256
259
  if (type.isUnionOrIntersection()) {
257
260
  return type.types.some(t => isTypeRecurser(t, predicate));
@@ -178,7 +178,7 @@ exports.default = (0, util_1.createRule)({
178
178
  }
179
179
  if (((0, util_1.isTypeFlagSet)(uncast, ts.TypeFlags.NonPrimitive) &&
180
180
  !(0, util_1.isTypeFlagSet)(cast, ts.TypeFlags.NonPrimitive)) ||
181
- (hasIndexSignature(uncast) && !hasIndexSignature(cast)) ||
181
+ hasIndexSignature(uncast) !== hasIndexSignature(cast) ||
182
182
  containsAny(uncast) ||
183
183
  containsAny(cast) ||
184
184
  (containsTypeVariable(cast) && !containsTypeVariable(uncast))) {
@@ -101,27 +101,25 @@ exports.default = (0, util_1.createRule)({
101
101
  for (const reference of smTypeParameterVariable.references) {
102
102
  if (reference.isTypeReference) {
103
103
  const referenceNode = reference.identifier;
104
- const isComplexType = constraint?.type === utils_1.AST_NODE_TYPES.TSUnionType ||
104
+ const isWeakPrecedenceConstraint = constraint?.type === utils_1.AST_NODE_TYPES.TSUnionType ||
105
105
  constraint?.type === utils_1.AST_NODE_TYPES.TSIntersectionType ||
106
- constraint?.type === utils_1.AST_NODE_TYPES.TSConditionalType;
107
- const hasMatchingAncestorType = [
108
- utils_1.AST_NODE_TYPES.TSArrayType,
109
- utils_1.AST_NODE_TYPES.TSIndexedAccessType,
110
- utils_1.AST_NODE_TYPES.TSIntersectionType,
111
- utils_1.AST_NODE_TYPES.TSUnionType,
112
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
113
- ].some(type => referenceNode.parent.parent.type === type);
114
- if (isComplexType && hasMatchingAncestorType) {
115
- const fixResult = (0, util_1.getWrappingFixer)({
116
- node: referenceNode,
117
- innerNode: constraint,
118
- sourceCode: context.sourceCode,
119
- wrap: constraintNode => constraintNode,
120
- })(fixer);
121
- yield fixResult;
106
+ constraint?.type === utils_1.AST_NODE_TYPES.TSConditionalType ||
107
+ constraint?.type === utils_1.AST_NODE_TYPES.TSTypeOperator ||
108
+ constraint?.type === utils_1.AST_NODE_TYPES.TSFunctionType ||
109
+ constraint?.type === utils_1.AST_NODE_TYPES.TSConstructorType;
110
+ const grandparent = (0, util_1.nullThrows)(referenceNode.parent.parent, util_1.NullThrowsReasons.MissingParent);
111
+ const isWeakPrecedenceTypeParent = grandparent.type === utils_1.AST_NODE_TYPES.TSArrayType ||
112
+ grandparent.type === utils_1.AST_NODE_TYPES.TSIndexedAccessType ||
113
+ grandparent.type === utils_1.AST_NODE_TYPES.TSIntersectionType ||
114
+ grandparent.type === utils_1.AST_NODE_TYPES.TSUnionType ||
115
+ grandparent.type === utils_1.AST_NODE_TYPES.TSConditionalType ||
116
+ grandparent.type === utils_1.AST_NODE_TYPES.TSTypeOperator;
117
+ if (isWeakPrecedenceConstraint &&
118
+ isWeakPrecedenceTypeParent) {
119
+ yield fixer.replaceText(referenceNode.parent, `(${constraintText})`);
122
120
  }
123
121
  else {
124
- yield fixer.replaceText(referenceNode, constraintText);
122
+ yield fixer.replaceText(referenceNode.parent, constraintText);
125
123
  }
126
124
  }
127
125
  }
@@ -73,7 +73,6 @@ function isStrongPrecedenceNode(innerNode) {
73
73
  return (innerNode.type === utils_1.AST_NODE_TYPES.Literal ||
74
74
  innerNode.type === utils_1.AST_NODE_TYPES.Identifier ||
75
75
  innerNode.type === utils_1.AST_NODE_TYPES.TSTypeReference ||
76
- innerNode.type === utils_1.AST_NODE_TYPES.TSTypeOperator ||
77
76
  innerNode.type === utils_1.AST_NODE_TYPES.ArrayExpression ||
78
77
  innerNode.type === utils_1.AST_NODE_TYPES.ObjectExpression ||
79
78
  innerNode.type === utils_1.AST_NODE_TYPES.MemberExpression ||
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@typescript-eslint/eslint-plugin",
3
- "version": "8.70.1-alpha.1",
3
+ "version": "8.70.1-alpha.11",
4
4
  "description": "TypeScript plugin for ESLint",
5
5
  "files": [
6
6
  "dist",
@@ -47,10 +47,10 @@
47
47
  ],
48
48
  "dependencies": {
49
49
  "@eslint-community/regexpp": "^4.12.2",
50
- "@typescript-eslint/scope-manager": "8.70.1-alpha.1",
51
- "@typescript-eslint/type-utils": "8.70.1-alpha.1",
52
- "@typescript-eslint/utils": "8.70.1-alpha.1",
53
- "@typescript-eslint/visitor-keys": "8.70.1-alpha.1",
50
+ "@typescript-eslint/scope-manager": "8.70.1-alpha.11",
51
+ "@typescript-eslint/type-utils": "8.70.1-alpha.11",
52
+ "@typescript-eslint/utils": "8.70.1-alpha.11",
53
+ "@typescript-eslint/visitor-keys": "8.70.1-alpha.11",
54
54
  "ignore": "^7.0.5",
55
55
  "natural-compare": "^1.4.0",
56
56
  "ts-api-utils": "^2.5.0"
@@ -60,8 +60,8 @@
60
60
  "@types/mdast": "^4.0.4",
61
61
  "@types/natural-compare": "^1.4.3",
62
62
  "@types/react": "^18.3.21",
63
- "@typescript-eslint/rule-schema-to-typescript-types": "8.70.1-alpha.1",
64
- "@typescript-eslint/rule-tester": "8.70.1-alpha.1",
63
+ "@typescript-eslint/rule-schema-to-typescript-types": "8.70.1-alpha.11",
64
+ "@typescript-eslint/rule-tester": "8.70.1-alpha.11",
65
65
  "@typescript/native": "npm:typescript@^7.0.2",
66
66
  "@vitest/coverage-v8": "^4.0.18",
67
67
  "ajv": "^6.12.6",
@@ -81,7 +81,7 @@
81
81
  "vitest": "^4.0.18"
82
82
  },
83
83
  "peerDependencies": {
84
- "@typescript-eslint/parser": "^8.70.1-alpha.1",
84
+ "@typescript-eslint/parser": "^8.70.1-alpha.11",
85
85
  "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
86
86
  "typescript": ">=4.8.4 <6.1.0"
87
87
  },