@typescript-eslint/eslint-plugin 6.16.0 → 6.17.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/dist/rules/no-floating-promises.js +44 -5
- package/dist/rules/no-floating-promises.js.map +1 -1
- package/dist/rules/no-restricted-imports.js +10 -1
- package/dist/rules/no-restricted-imports.js.map +1 -1
- package/dist/rules/switch-exhaustiveness-check.js +107 -56
- package/dist/rules/switch-exhaustiveness-check.js.map +1 -1
- package/docs/rules/explicit-module-boundary-types.md +10 -15
- package/docs/rules/no-floating-promises.md +15 -0
- package/docs/rules/prefer-readonly-parameter-types.md +8 -5
- package/docs/rules/switch-exhaustiveness-check.md +41 -23
- package/package.json +8 -8
|
@@ -31,6 +31,9 @@ const messageBase = 'Promises must be awaited, end with a call to .catch, or end
|
|
|
31
31
|
const messageBaseVoid = 'Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler' +
|
|
32
32
|
' or be explicitly marked as ignored with the `void` operator.';
|
|
33
33
|
const messageRejectionHandler = 'A rejection handler that is not a function will be ignored.';
|
|
34
|
+
const messagePromiseArray = "An array of Promises may be unintentional. Consider handling the promises' fulfillment or rejection with Promise.all or similar.";
|
|
35
|
+
const messagePromiseArrayVoid = "An array of Promises may be unintentional. Consider handling the promises' fulfillment or rejection with Promise.all or similar," +
|
|
36
|
+
' or explicitly marking the expression as ignored with the `void` operator.';
|
|
34
37
|
exports.default = (0, util_1.createRule)({
|
|
35
38
|
name: 'no-floating-promises',
|
|
36
39
|
meta: {
|
|
@@ -47,6 +50,8 @@ exports.default = (0, util_1.createRule)({
|
|
|
47
50
|
floatingFixVoid: 'Add void operator to ignore.',
|
|
48
51
|
floatingUselessRejectionHandler: messageBase + ' ' + messageRejectionHandler,
|
|
49
52
|
floatingUselessRejectionHandlerVoid: messageBaseVoid + ' ' + messageRejectionHandler,
|
|
53
|
+
floatingPromiseArray: messagePromiseArray,
|
|
54
|
+
floatingPromiseArrayVoid: messagePromiseArrayVoid,
|
|
50
55
|
},
|
|
51
56
|
schema: [
|
|
52
57
|
{
|
|
@@ -84,9 +89,17 @@ exports.default = (0, util_1.createRule)({
|
|
|
84
89
|
if (expression.type === utils_1.AST_NODE_TYPES.ChainExpression) {
|
|
85
90
|
expression = expression.expression;
|
|
86
91
|
}
|
|
87
|
-
const { isUnhandled, nonFunctionHandler } = isUnhandledPromise(checker, expression);
|
|
92
|
+
const { isUnhandled, nonFunctionHandler, promiseArray } = isUnhandledPromise(checker, expression);
|
|
88
93
|
if (isUnhandled) {
|
|
89
|
-
if (
|
|
94
|
+
if (promiseArray) {
|
|
95
|
+
context.report({
|
|
96
|
+
node,
|
|
97
|
+
messageId: options.ignoreVoid
|
|
98
|
+
? 'floatingPromiseArrayVoid'
|
|
99
|
+
: 'floatingPromiseArray',
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
else if (options.ignoreVoid) {
|
|
90
103
|
context.report({
|
|
91
104
|
node,
|
|
92
105
|
messageId: nonFunctionHandler
|
|
@@ -177,8 +190,13 @@ exports.default = (0, util_1.createRule)({
|
|
|
177
190
|
// see what's inside it without checking the type of the overall expression.
|
|
178
191
|
return isUnhandledPromise(checker, node.argument);
|
|
179
192
|
}
|
|
193
|
+
const tsNode = services.esTreeNodeToTSNodeMap.get(node);
|
|
180
194
|
// Check the type. At this point it can't be unhandled if it isn't a promise
|
|
181
|
-
|
|
195
|
+
// or array thereof.
|
|
196
|
+
if (isPromiseArray(checker, tsNode)) {
|
|
197
|
+
return { isUnhandled: true, promiseArray: true };
|
|
198
|
+
}
|
|
199
|
+
if (!isPromiseLike(checker, tsNode)) {
|
|
182
200
|
return { isUnhandled: false };
|
|
183
201
|
}
|
|
184
202
|
if (node.type === utils_1.AST_NODE_TYPES.CallExpression) {
|
|
@@ -238,12 +256,33 @@ exports.default = (0, util_1.createRule)({
|
|
|
238
256
|
}
|
|
239
257
|
},
|
|
240
258
|
});
|
|
259
|
+
function isPromiseArray(checker, node) {
|
|
260
|
+
const type = checker.getTypeAtLocation(node);
|
|
261
|
+
for (const ty of tsutils
|
|
262
|
+
.unionTypeParts(type)
|
|
263
|
+
.map(t => checker.getApparentType(t))) {
|
|
264
|
+
if (checker.isArrayType(ty)) {
|
|
265
|
+
const arrayType = checker.getTypeArguments(ty)[0];
|
|
266
|
+
if (isPromiseLike(checker, node, arrayType)) {
|
|
267
|
+
return true;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
if (checker.isTupleType(ty)) {
|
|
271
|
+
for (const tupleElementType of checker.getTypeArguments(ty)) {
|
|
272
|
+
if (isPromiseLike(checker, node, tupleElementType)) {
|
|
273
|
+
return true;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
return false;
|
|
279
|
+
}
|
|
241
280
|
// Modified from tsutils.isThenable() to only consider thenables which can be
|
|
242
281
|
// rejected/caught via a second parameter. Original source (MIT licensed):
|
|
243
282
|
//
|
|
244
283
|
// https://github.com/ajafff/tsutils/blob/49d0d31050b44b81e918eae4fbaf1dfe7b7286af/util/type.ts#L95-L125
|
|
245
|
-
function isPromiseLike(checker, node) {
|
|
246
|
-
|
|
284
|
+
function isPromiseLike(checker, node, type) {
|
|
285
|
+
type ??= checker.getTypeAtLocation(node);
|
|
247
286
|
for (const ty of tsutils.unionTypeParts(checker.getApparentType(type))) {
|
|
248
287
|
const then = ty.getProperty('then');
|
|
249
288
|
if (then === undefined) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"no-floating-promises.js","sourceRoot":"","sources":["../../src/rules/no-floating-promises.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AACA,oDAA0D;AAC1D,sDAAwC;AACxC,+CAAiC;AAEjC,kCAKiB;
|
|
1
|
+
{"version":3,"file":"no-floating-promises.js","sourceRoot":"","sources":["../../src/rules/no-floating-promises.ts"],"names":[],"mappings":"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"}
|
|
@@ -121,6 +121,15 @@ function getRestrictedPatterns(options) {
|
|
|
121
121
|
}
|
|
122
122
|
return [];
|
|
123
123
|
}
|
|
124
|
+
function shouldCreateRule(baseRules, options) {
|
|
125
|
+
if (Object.keys(baseRules).length === 0 || options.length === 0) {
|
|
126
|
+
return false;
|
|
127
|
+
}
|
|
128
|
+
if (!isOptionsArrayOfStringOrObject(options)) {
|
|
129
|
+
return !!(options[0].paths?.length || options[0].patterns?.length);
|
|
130
|
+
}
|
|
131
|
+
return true;
|
|
132
|
+
}
|
|
124
133
|
exports.default = (0, util_1.createRule)({
|
|
125
134
|
name: 'no-restricted-imports',
|
|
126
135
|
meta: {
|
|
@@ -137,7 +146,7 @@ exports.default = (0, util_1.createRule)({
|
|
|
137
146
|
create(context) {
|
|
138
147
|
const rules = baseRule.create(context);
|
|
139
148
|
const { options } = context;
|
|
140
|
-
if (options
|
|
149
|
+
if (!shouldCreateRule(rules, options)) {
|
|
141
150
|
return {};
|
|
142
151
|
}
|
|
143
152
|
const restrictedPaths = getRestrictedPaths(options);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"no-restricted-imports.js","sourceRoot":"","sources":["../../src/rules/no-restricted-imports.ts"],"names":[],"mappings":";;;;;AACA,oDAA0D;
|
|
1
|
+
{"version":3,"file":"no-restricted-imports.js","sourceRoot":"","sources":["../../src/rules/no-restricted-imports.ts"],"names":[],"mappings":";;;;;AACA,oDAA0D;AAY1D,oDAA4B;AAM5B,kCAAqC;AACrC,iEAA8D;AAE9D,MAAM,QAAQ,GAAG,IAAA,qCAAiB,EAAC,uBAAuB,CAAC,CAAC;AAK5D,iFAAiF;AACjF,gFAAgF;AAChF,kDAAkD;AAClD,MAAM,SAAS,GAAG,CAAI,MAAe,EAAE,QAAW,EAAK,EAAE;IACvD,IAAI,CAAC;QACH,OAAO,MAAM,EAAE,CAAC;IAClB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,QAAQ,CAAC;IAClB,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,UAAU,GAAG,QAAQ,CAAC,IAAI,CAAC,MAwChC,CAAC;AAEF,MAAM,4BAA4B,GAA0C;IAC1E,gBAAgB,EAAE;QAChB,IAAI,EAAE,SAAS;QACf,WAAW,EAAE,sDAAsD;KACpE;CACF,CAAC;AAEF,MAAM,uBAAuB,GAA2B;IACtD,IAAI,EAAE,OAAO;IACb,KAAK,EAAE;QACL,KAAK,EAAE;YACL,EAAE,IAAI,EAAE,QAAQ,EAAE;YAClB;gBACE,IAAI,EAAE,QAAQ;gBACd,oBAAoB,EAAE,KAAK;gBAC3B,UAAU,EAAE;oBACV,GAAG,SAAS,CACV,GAAG,EAAE,CACH,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;yBACzD,UAAU,EACf,SAAS,CACV;oBACD,GAAG,4BAA4B;iBAChC;gBACD,QAAQ,EAAE,SAAS,CACjB,GAAG,EAAE,CACH,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;qBACzD,QAAQ,EACb,SAAS,CACV;aACF;SACF;KACF;IACD,WAAW,EAAE,IAAI;CAClB,CAAC;AAEF,MAAM,8BAA8B,GAA2B;IAC7D,KAAK,EAAE;QACL;YACE,IAAI,EAAE,OAAO;YACb,KAAK,EAAE;gBACL,IAAI,EAAE,QAAQ;aACf;YACD,WAAW,EAAE,IAAI;SAClB;QACD;YACE,IAAI,EAAE,OAAO;YACb,KAAK,EAAE;gBACL,IAAI,EAAE,QAAQ;gBACd,oBAAoB,EAAE,KAAK;gBAC3B,UAAU,EAAE;oBACV,GAAG,SAAS,CACV,GAAG,EAAE,CACH,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK;yBAC5D,UAAU,EACf,SAAS,CACV;oBACD,GAAG,4BAA4B;iBAChC;gBACD,QAAQ,EAAE,SAAS,CACjB,GAAG,EAAE,CACH,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK;qBAC5D,QAAQ,EACb,EAAE,CACH;aACF;YACD,WAAW,EAAE,IAAI;SAClB;KACF;CACF,CAAC;AAEF,MAAM,MAAM,GAA2B;IACrC,KAAK,EAAE;QACL,uBAAuB;QACvB;YACE,IAAI,EAAE,OAAO;YACb,KAAK,EAAE;gBACL;oBACE,IAAI,EAAE,QAAQ;oBACd,UAAU,EAAE;wBACV,KAAK,EAAE,uBAAuB;wBAC9B,QAAQ,EAAE,8BAA8B;qBACzC;oBACD,oBAAoB,EAAE,KAAK;iBAC5B;aACF;YACD,eAAe,EAAE,KAAK;SACvB;KACF;CACF,CAAC;AAEF,SAAS,eAAe,CACtB,GAAY;IAEZ,OAAO,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;AAC5D,CAAC;AAED,SAAS,kBAAkB,CACzB,GAAY;IAEZ,OAAO,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;AAC/D,CAAC;AAED,SAAS,8BAA8B,CACrC,OAAgB;IAEhB,IAAI,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAChC,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,kBAAkB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACnC,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,kBAAkB,CAAC,OAAgB;IAC1C,IAAI,8BAA8B,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5C,OAAO,OAAO,CAAC;IACjB,CAAC;IACD,IAAI,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAChC,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IAC1B,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,SAAS,qBAAqB,CAC5B,OAAgB;IAEhB,IAAI,kBAAkB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACnC,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;IAC7B,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,SAAS,gBAAgB,CACvB,SAAuB,EACvB,OAAgB;IAEhB,IAAI,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAChE,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,CAAC,8BAA8B,CAAC,OAAO,CAAC,EAAE,CAAC;QAC7C,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACrE,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,kBAAe,IAAA,iBAAU,EAAsB;IAC7C,IAAI,EAAE,uBAAuB;IAC7B,IAAI,EAAE;QACJ,IAAI,EAAE,YAAY;QAClB,IAAI,EAAE;YACJ,WAAW,EAAE,oDAAoD;YACjE,eAAe,EAAE,IAAI;SACtB;QACD,QAAQ,EAAE,QAAQ,CAAC,IAAI,CAAC,QAAQ;QAChC,OAAO,EAAE,QAAQ,CAAC,IAAI,CAAC,OAAO;QAC9B,MAAM;KACP;IACD,cAAc,EAAE,EAAE;IAClB,MAAM,CAAC,OAAO;QACZ,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACvC,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;QAE5B,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE,CAAC;YACtC,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,MAAM,eAAe,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAC;QACpD,MAAM,4BAA4B,GAAG,IAAI,GAAG,EAAU,CAAC;QACvD,KAAK,MAAM,cAAc,IAAI,eAAe,EAAE,CAAC;YAC7C,IACE,OAAO,cAAc,KAAK,QAAQ;gBAClC,cAAc,CAAC,gBAAgB,EAC/B,CAAC;gBACD,4BAA4B,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;YACxD,CAAC;QACH,CAAC;QACD,SAAS,uBAAuB,CAAC,YAAoB;YACnD,OAAO,4BAA4B,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QACxD,CAAC;QAED,MAAM,kBAAkB,GAAG,qBAAqB,CAAC,OAAO,CAAC,CAAC;QAC1D,MAAM,yBAAyB,GAAa,EAAE,CAAC;QAC/C,KAAK,MAAM,iBAAiB,IAAI,kBAAkB,EAAE,CAAC;YACnD,IACE,OAAO,iBAAiB,KAAK,QAAQ;gBACrC,iBAAiB,CAAC,gBAAgB,EAClC,CAAC;gBACD,sDAAsD;gBACtD,yBAAyB,CAAC,IAAI,CAC5B,IAAA,gBAAM,EAAC;oBACL,kBAAkB,EAAE,IAAI;oBACxB,UAAU,EAAE,CAAC,iBAAiB,CAAC,aAAa;iBAC7C,CAAC,CAAC,GAAG,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAChC,CAAC;YACJ,CAAC;QACH,CAAC;QACD,SAAS,0BAA0B,CAAC,YAAoB;YACtD,OAAO;YACL,kEAAkE;YAClE,yBAAyB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CACzE,CAAC;QACJ,CAAC;QAED,SAAS,eAAe,CAAC,IAAgC;YACvD,IACE,IAAI,CAAC,UAAU,KAAK,MAAM;gBAC1B,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC;oBACzB,IAAI,CAAC,UAAU,CAAC,KAAK,CACnB,SAAS,CAAC,EAAE,CACV,SAAS,CAAC,IAAI,KAAK,sBAAc,CAAC,eAAe;wBACjD,SAAS,CAAC,UAAU,KAAK,MAAM,CAClC,CAAC,EACJ,CAAC;gBACD,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;gBAC9C,IACE,CAAC,uBAAuB,CAAC,YAAY,CAAC;oBACtC,CAAC,0BAA0B,CAAC,YAAY,CAAC,EACzC,CAAC;oBACD,OAAO,KAAK,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;gBACvC,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,OAAO,KAAK,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;YACvC,CAAC;QACH,CAAC;QAED,OAAO;YACL,yBAAyB,CACvB,IAAwC;gBAExC,IACE,IAAI,CAAC,eAAe,CAAC,IAAI;oBACvB,sBAAc,CAAC,yBAAyB;oBAC1C,IAAI,CAAC,eAAe,CAAC,UAAU,CAAC,IAAI,KAAK,sBAAc,CAAC,OAAO;oBAC/D,OAAO,IAAI,CAAC,eAAe,CAAC,UAAU,CAAC,KAAK,KAAK,QAAQ,EACzD,CAAC;oBACD,MAAM,iBAAiB,GAAG;wBACxB,GAAG,IAAI;wBACP,IAAI,EAAE,sBAAc,CAAC,iBAAiB;wBACtC,MAAM,EAAE,IAAI,CAAC,eAAe,CAAC,UAAU;wBACvC,UAAU,EAAE,EAAE;wBACd,UAAU,EAAE,EAAE;wBACd,UAAU,EAAE;4BACV;gCACE,GAAG,IAAI,CAAC,EAAE;gCACV,IAAI,EAAE,sBAAc,CAAC,sBAAsB;gCAC3C,KAAK,EAAE,IAAI,CAAC,EAAE;6BACf;yBACF;qBACmC,CAAC;oBACvC,OAAO,eAAe,CAAC,iBAAiB,CAAC,CAAC;gBAC5C,CAAC;YACH,CAAC;YACD,iBAAiB,EAAE,eAAe;YAClC,gCAAgC,CAC9B,IAEC;gBAED,IACE,IAAI,CAAC,UAAU,KAAK,MAAM;oBAC1B,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC;wBACzB,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC,SAAS,CAAC,UAAU,KAAK,MAAM,CAAC,CAAC,EACtE,CAAC;oBACD,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;oBAC9C,IACE,CAAC,uBAAuB,CAAC,YAAY,CAAC;wBACtC,CAAC,0BAA0B,CAAC,YAAY,CAAC,EACzC,CAAC;wBACD,OAAO,KAAK,CAAC,sBAAsB,CAAC,IAAI,CAAC,CAAC;oBAC5C,CAAC;gBACH,CAAC;qBAAM,CAAC;oBACN,OAAO,KAAK,CAAC,sBAAsB,CAAC,IAAI,CAAC,CAAC;gBAC5C,CAAC;YACH,CAAC;YACD,oBAAoB,EAAE,KAAK,CAAC,oBAAoB;SACjD,CAAC;IACJ,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -39,33 +39,101 @@ exports.default = (0, util_1.createRule)({
|
|
|
39
39
|
schema: [
|
|
40
40
|
{
|
|
41
41
|
type: 'object',
|
|
42
|
-
additionalProperties: false,
|
|
43
42
|
properties: {
|
|
43
|
+
allowDefaultCaseForExhaustiveSwitch: {
|
|
44
|
+
description: `If 'true', allow 'default' cases on switch statements with exhaustive cases.`,
|
|
45
|
+
type: 'boolean',
|
|
46
|
+
},
|
|
44
47
|
requireDefaultForNonUnion: {
|
|
45
48
|
description: `If 'true', require a 'default' clause for switches on non-union types.`,
|
|
46
49
|
type: 'boolean',
|
|
47
50
|
},
|
|
48
51
|
},
|
|
52
|
+
additionalProperties: false,
|
|
49
53
|
},
|
|
50
54
|
],
|
|
51
55
|
messages: {
|
|
52
56
|
switchIsNotExhaustive: 'Switch is not exhaustive. Cases not matched: {{missingBranches}}',
|
|
57
|
+
dangerousDefaultCase: 'The switch statement is exhaustive, so the default case is unnecessary.',
|
|
53
58
|
addMissingCases: 'Add branches for missing cases.',
|
|
54
59
|
},
|
|
55
60
|
},
|
|
56
|
-
defaultOptions: [
|
|
57
|
-
|
|
61
|
+
defaultOptions: [
|
|
62
|
+
{
|
|
63
|
+
allowDefaultCaseForExhaustiveSwitch: true,
|
|
64
|
+
requireDefaultForNonUnion: false,
|
|
65
|
+
},
|
|
66
|
+
],
|
|
67
|
+
create(context, [{ allowDefaultCaseForExhaustiveSwitch, requireDefaultForNonUnion }]) {
|
|
58
68
|
const sourceCode = (0, eslint_utils_1.getSourceCode)(context);
|
|
59
69
|
const services = (0, util_1.getParserServices)(context);
|
|
60
70
|
const checker = services.program.getTypeChecker();
|
|
61
71
|
const compilerOptions = services.program.getCompilerOptions();
|
|
72
|
+
function getSwitchMetadata(node) {
|
|
73
|
+
const defaultCase = node.cases.find(switchCase => switchCase.test == null);
|
|
74
|
+
const discriminantType = (0, util_1.getConstrainedTypeAtLocation)(services, node.discriminant);
|
|
75
|
+
const symbolName = discriminantType.getSymbol()?.escapedName;
|
|
76
|
+
if (!discriminantType.isUnion()) {
|
|
77
|
+
return {
|
|
78
|
+
symbolName,
|
|
79
|
+
missingBranchTypes: [],
|
|
80
|
+
defaultCase,
|
|
81
|
+
isUnion: false,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
const caseTypes = new Set();
|
|
85
|
+
for (const switchCase of node.cases) {
|
|
86
|
+
// If the `test` property of the switch case is `null`, then we are on a
|
|
87
|
+
// `default` case.
|
|
88
|
+
if (switchCase.test == null) {
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
const caseType = (0, util_1.getConstrainedTypeAtLocation)(services, switchCase.test);
|
|
92
|
+
caseTypes.add(caseType);
|
|
93
|
+
}
|
|
94
|
+
const unionTypes = tsutils.unionTypeParts(discriminantType);
|
|
95
|
+
const missingBranchTypes = unionTypes.filter(unionType => !caseTypes.has(unionType));
|
|
96
|
+
return {
|
|
97
|
+
symbolName,
|
|
98
|
+
missingBranchTypes,
|
|
99
|
+
defaultCase,
|
|
100
|
+
isUnion: true,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
function checkSwitchExhaustive(node, switchMetadata) {
|
|
104
|
+
const { missingBranchTypes, symbolName, defaultCase } = switchMetadata;
|
|
105
|
+
// We only trigger the rule if a `default` case does not exist, since that
|
|
106
|
+
// would disqualify the switch statement from having cases that exactly
|
|
107
|
+
// match the members of a union.
|
|
108
|
+
if (missingBranchTypes.length > 0 && defaultCase === undefined) {
|
|
109
|
+
context.report({
|
|
110
|
+
node: node.discriminant,
|
|
111
|
+
messageId: 'switchIsNotExhaustive',
|
|
112
|
+
data: {
|
|
113
|
+
missingBranches: missingBranchTypes
|
|
114
|
+
.map(missingType => tsutils.isTypeFlagSet(missingType, ts.TypeFlags.ESSymbolLike)
|
|
115
|
+
? `typeof ${missingType.getSymbol()?.escapedName}`
|
|
116
|
+
: checker.typeToString(missingType))
|
|
117
|
+
.join(' | '),
|
|
118
|
+
},
|
|
119
|
+
suggest: [
|
|
120
|
+
{
|
|
121
|
+
messageId: 'addMissingCases',
|
|
122
|
+
fix(fixer) {
|
|
123
|
+
return fixSwitch(fixer, node, missingBranchTypes, symbolName?.toString());
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
],
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
}
|
|
62
130
|
function fixSwitch(fixer, node, missingBranchTypes, // null means default branch
|
|
63
131
|
symbolName) {
|
|
64
132
|
const lastCase = node.cases.length > 0 ? node.cases[node.cases.length - 1] : null;
|
|
65
133
|
const caseIndent = lastCase
|
|
66
134
|
? ' '.repeat(lastCase.loc.start.column)
|
|
67
|
-
: //
|
|
68
|
-
//
|
|
135
|
+
: // If there are no cases, use indentation of the switch statement and
|
|
136
|
+
// leave it to the user to format it correctly.
|
|
69
137
|
' '.repeat(node.loc.start.column);
|
|
70
138
|
const missingCases = [];
|
|
71
139
|
for (const missingBranchType of missingBranchTypes) {
|
|
@@ -73,14 +141,16 @@ exports.default = (0, util_1.createRule)({
|
|
|
73
141
|
missingCases.push(`default: { throw new Error('default case') }`);
|
|
74
142
|
continue;
|
|
75
143
|
}
|
|
76
|
-
// While running this rule on checker.ts of TypeScript
|
|
144
|
+
// While running this rule on the "checker.ts" file of TypeScript, the
|
|
77
145
|
// the fix introduced a compiler error due to:
|
|
78
146
|
//
|
|
147
|
+
// ```ts
|
|
79
148
|
// type __String = (string & {
|
|
80
|
-
//
|
|
81
|
-
//
|
|
82
|
-
//
|
|
83
|
-
//
|
|
149
|
+
// __escapedIdentifier: void;
|
|
150
|
+
// }) | (void & {
|
|
151
|
+
// __escapedIdentifier: void;
|
|
152
|
+
// }) | InternalSymbolName;
|
|
153
|
+
// ```
|
|
84
154
|
//
|
|
85
155
|
// The following check fixes it.
|
|
86
156
|
if (missingBranchType.isIntersection()) {
|
|
@@ -107,72 +177,53 @@ exports.default = (0, util_1.createRule)({
|
|
|
107
177
|
if (lastCase) {
|
|
108
178
|
return fixer.insertTextAfter(lastCase, `\n${fixString}`);
|
|
109
179
|
}
|
|
110
|
-
//
|
|
180
|
+
// There were no existing cases.
|
|
111
181
|
const openingBrace = sourceCode.getTokenAfter(node.discriminant, util_1.isOpeningBraceToken);
|
|
112
182
|
const closingBrace = sourceCode.getTokenAfter(node.discriminant, util_1.isClosingBraceToken);
|
|
113
183
|
return fixer.replaceTextRange([openingBrace.range[0], closingBrace.range[1]], ['{', fixString, `${caseIndent}}`].join('\n'));
|
|
114
184
|
}
|
|
115
|
-
function
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
185
|
+
function checkSwitchUnnecessaryDefaultCase(switchMetadata) {
|
|
186
|
+
if (allowDefaultCaseForExhaustiveSwitch) {
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
const { missingBranchTypes, defaultCase } = switchMetadata;
|
|
190
|
+
if (missingBranchTypes.length === 0 && defaultCase !== undefined) {
|
|
191
|
+
context.report({
|
|
192
|
+
node: defaultCase,
|
|
193
|
+
messageId: 'dangerousDefaultCase',
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
function checkSwitchNoUnionDefaultCase(node, switchMetadata) {
|
|
198
|
+
if (!requireDefaultForNonUnion) {
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
const { isUnion, defaultCase } = switchMetadata;
|
|
202
|
+
if (!isUnion && defaultCase === undefined) {
|
|
133
203
|
context.report({
|
|
134
204
|
node: node.discriminant,
|
|
135
205
|
messageId: 'switchIsNotExhaustive',
|
|
136
206
|
data: {
|
|
137
|
-
missingBranches:
|
|
138
|
-
.map(missingType => tsutils.isTypeFlagSet(missingType, ts.TypeFlags.ESSymbolLike)
|
|
139
|
-
? `typeof ${missingType.getSymbol()?.escapedName}`
|
|
140
|
-
: checker.typeToString(missingType))
|
|
141
|
-
.join(' | '),
|
|
207
|
+
missingBranches: 'default',
|
|
142
208
|
},
|
|
143
209
|
suggest: [
|
|
144
210
|
{
|
|
145
211
|
messageId: 'addMissingCases',
|
|
146
212
|
fix(fixer) {
|
|
147
|
-
return fixSwitch(fixer, node,
|
|
213
|
+
return fixSwitch(fixer, node, [null]);
|
|
148
214
|
},
|
|
149
215
|
},
|
|
150
216
|
],
|
|
151
217
|
});
|
|
152
218
|
}
|
|
153
|
-
else if (requireDefaultForNonUnion) {
|
|
154
|
-
const hasDefault = node.cases.some(switchCase => switchCase.test == null);
|
|
155
|
-
if (!hasDefault) {
|
|
156
|
-
context.report({
|
|
157
|
-
node: node.discriminant,
|
|
158
|
-
messageId: 'switchIsNotExhaustive',
|
|
159
|
-
data: {
|
|
160
|
-
missingBranches: 'default',
|
|
161
|
-
},
|
|
162
|
-
suggest: [
|
|
163
|
-
{
|
|
164
|
-
messageId: 'addMissingCases',
|
|
165
|
-
fix(fixer) {
|
|
166
|
-
return fixSwitch(fixer, node, [null]);
|
|
167
|
-
},
|
|
168
|
-
},
|
|
169
|
-
],
|
|
170
|
-
});
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
219
|
}
|
|
174
220
|
return {
|
|
175
|
-
SwitchStatement
|
|
221
|
+
SwitchStatement(node) {
|
|
222
|
+
const switchMetadata = getSwitchMetadata(node);
|
|
223
|
+
checkSwitchExhaustive(node, switchMetadata);
|
|
224
|
+
checkSwitchUnnecessaryDefaultCase(switchMetadata);
|
|
225
|
+
checkSwitchNoUnionDefaultCase(node, switchMetadata);
|
|
226
|
+
},
|
|
176
227
|
};
|
|
177
228
|
},
|
|
178
229
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"switch-exhaustiveness-check.js","sourceRoot":"","sources":["../../src/rules/switch-exhaustiveness-check.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AACA,wEAAsE;AACtE,sDAAwC;AACxC,+CAAiC;AAEjC,kCAOiB;
|
|
1
|
+
{"version":3,"file":"switch-exhaustiveness-check.js","sourceRoot":"","sources":["../../src/rules/switch-exhaustiveness-check.ts"],"names":[],"mappings":"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"}
|
|
@@ -22,11 +22,6 @@ export function test() {
|
|
|
22
22
|
return;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
// Should indicate that a number is returned
|
|
26
|
-
export default function () {
|
|
27
|
-
return 1;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
25
|
// Should indicate that a string is returned
|
|
31
26
|
export var arrowFn = () => 'test';
|
|
32
27
|
|
|
@@ -45,16 +40,11 @@ export class Test {
|
|
|
45
40
|
### ✅ Correct
|
|
46
41
|
|
|
47
42
|
```ts
|
|
48
|
-
//
|
|
49
|
-
function test() {
|
|
43
|
+
// A function with no return value (void)
|
|
44
|
+
export function test(): void {
|
|
50
45
|
return;
|
|
51
46
|
}
|
|
52
47
|
|
|
53
|
-
// A return value of type number
|
|
54
|
-
export var fn = function (): number {
|
|
55
|
-
return 1;
|
|
56
|
-
};
|
|
57
|
-
|
|
58
48
|
// A return value of type string
|
|
59
49
|
export var arrowFn = (): string => 'test';
|
|
60
50
|
|
|
@@ -62,12 +52,17 @@ export var arrowFn = (): string => 'test';
|
|
|
62
52
|
export var arrowFn = (arg: string): string => `test ${arg}`;
|
|
63
53
|
export var arrowFn = (arg: unknown): string => `test ${arg}`;
|
|
64
54
|
|
|
65
|
-
|
|
66
|
-
class
|
|
67
|
-
method() {
|
|
55
|
+
export class Test {
|
|
56
|
+
// A class method with no return value (void)
|
|
57
|
+
method(): void {
|
|
68
58
|
return;
|
|
69
59
|
}
|
|
70
60
|
}
|
|
61
|
+
|
|
62
|
+
// The function does not apply because it is not an exported function.
|
|
63
|
+
function test() {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
71
66
|
```
|
|
72
67
|
|
|
73
68
|
## Options
|
|
@@ -17,6 +17,13 @@ Valid ways of handling a Promise-valued statement include:
|
|
|
17
17
|
- Calling its `.then()` with two arguments
|
|
18
18
|
- Calling its `.catch()` with one argument
|
|
19
19
|
|
|
20
|
+
This rule also reports when an Array containing Promises is created and not properly handled. The main way to resolve this is by using one of the Promise concurrency methods to create a single Promise, then handling that according to the procedure above. These methods include:
|
|
21
|
+
|
|
22
|
+
- `Promise.all()`,
|
|
23
|
+
- `Promise.allSettled()`,
|
|
24
|
+
- `Promise.any()`
|
|
25
|
+
- `Promise.race()`
|
|
26
|
+
|
|
20
27
|
:::tip
|
|
21
28
|
`no-floating-promises` only detects unhandled Promise _statements_.
|
|
22
29
|
See [`no-misused-promises`](./no-misused-promises.md) for detecting code that provides Promises to _logical_ locations such as if statements.
|
|
@@ -40,6 +47,8 @@ returnsPromise().then(() => {});
|
|
|
40
47
|
Promise.reject('value').catch();
|
|
41
48
|
|
|
42
49
|
Promise.reject('value').finally();
|
|
50
|
+
|
|
51
|
+
[1, 2, 3].map(async x => x + 1);
|
|
43
52
|
```
|
|
44
53
|
|
|
45
54
|
### ✅ Correct
|
|
@@ -59,6 +68,8 @@ returnsPromise().then(
|
|
|
59
68
|
Promise.reject('value').catch(() => {});
|
|
60
69
|
|
|
61
70
|
await Promise.reject('value').finally(() => {});
|
|
71
|
+
|
|
72
|
+
await Promise.all([1, 2, 3].map(async x => x + 1));
|
|
62
73
|
```
|
|
63
74
|
|
|
64
75
|
## Options
|
|
@@ -106,3 +117,7 @@ You might consider using `void`s and/or [ESLint disable comments](https://eslint
|
|
|
106
117
|
## Related To
|
|
107
118
|
|
|
108
119
|
- [`no-misused-promises`](./no-misused-promises.md)
|
|
120
|
+
|
|
121
|
+
## Further Reading
|
|
122
|
+
|
|
123
|
+
- ["Using Promises" MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises). Note especially the sections on [Promise rejection events](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises#promise_rejection_events) and [Composition](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises#composition).
|
|
@@ -57,7 +57,7 @@ interface Foo {
|
|
|
57
57
|
interface Foo {
|
|
58
58
|
new (arg: string[]): void;
|
|
59
59
|
}
|
|
60
|
-
const x = { foo(arg: string[]): void
|
|
60
|
+
const x = { foo(arg: string[]): void {} };
|
|
61
61
|
function foo(arg: string[]);
|
|
62
62
|
type Foo = (arg: string[]) => void;
|
|
63
63
|
interface Foo {
|
|
@@ -91,7 +91,7 @@ interface CustomFunction {
|
|
|
91
91
|
}
|
|
92
92
|
function custom2(arg: CustomFunction) {}
|
|
93
93
|
|
|
94
|
-
function union(arg: readonly string[] | ReadonlyArray<number
|
|
94
|
+
function union(arg: readonly string[] | ReadonlyArray<number>) {}
|
|
95
95
|
|
|
96
96
|
function primitive1(arg: string) {}
|
|
97
97
|
function primitive2(arg: number) {}
|
|
@@ -105,8 +105,11 @@ function primitive9(arg: string | number | undefined) {}
|
|
|
105
105
|
|
|
106
106
|
function fnSig(arg: () => void) {}
|
|
107
107
|
|
|
108
|
-
enum Foo {
|
|
109
|
-
|
|
108
|
+
enum Foo {
|
|
109
|
+
a,
|
|
110
|
+
b,
|
|
111
|
+
}
|
|
112
|
+
function enumArg(arg: Foo) {}
|
|
110
113
|
|
|
111
114
|
function symb1(arg: symbol) {}
|
|
112
115
|
const customSymbol = Symbol('a');
|
|
@@ -119,7 +122,7 @@ interface Foo {
|
|
|
119
122
|
interface Foo {
|
|
120
123
|
new (arg: readonly string[]): void;
|
|
121
124
|
}
|
|
122
|
-
const x = { foo(arg: readonly string[]): void
|
|
125
|
+
const x = { foo(arg: readonly string[]): void {} };
|
|
123
126
|
function foo(arg: readonly string[]);
|
|
124
127
|
type Foo = (arg: readonly string[]) => void;
|
|
125
128
|
interface Foo {
|
|
@@ -6,12 +6,51 @@ description: 'Require switch-case statements to be exhaustive.'
|
|
|
6
6
|
>
|
|
7
7
|
> See **https://typescript-eslint.io/rules/switch-exhaustiveness-check** for documentation.
|
|
8
8
|
|
|
9
|
-
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
|
|
9
|
+
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 possible type in the union or the enum.
|
|
10
10
|
However, if the union type or the enum changes, it's easy to forget to modify the cases to account for any new types.
|
|
11
11
|
|
|
12
12
|
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.
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
## Options
|
|
15
|
+
|
|
16
|
+
### `"allowDefaultCaseForExhaustiveSwitch"`
|
|
17
|
+
|
|
18
|
+
Defaults to true. If set to false, this rule will also report when a `switch` statement has a case for everything in a union and _also_ contains a `default` case. Thus, by setting this option to false, the rule becomes stricter.
|
|
19
|
+
|
|
20
|
+
When a `switch` statement over a union type is exhaustive, a final `default` case would be a form of dead code.
|
|
21
|
+
Additionally, if a new value is added to the union type, a `default` would prevent the `switch-exhaustiveness-check` rule from reporting on the new case not being handled in the `switch` statement.
|
|
22
|
+
|
|
23
|
+
#### `"allowDefaultCaseForExhaustiveSwitch"` Caveats
|
|
24
|
+
|
|
25
|
+
It can sometimes be useful to include a redundant `default` case on an exhaustive `switch` statement if it's possible for values to have types not represented by the union type.
|
|
26
|
+
For example, in applications that can have version mismatches between clients and servers, it's possible for a server running a newer software version to send a value not recognized by the client's older typings.
|
|
27
|
+
|
|
28
|
+
If your project has a small number of intentionally redundant `default` cases, you might want to use an [inline ESLint disable comment](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) for each of them.
|
|
29
|
+
|
|
30
|
+
If your project has many intentionally redundant `default` cases, you may want to disable `allowDefaultCaseForExhaustiveSwitch` and use the [`default-case` core ESLint rule](https://eslint.org/docs/latest/rules/default-case) along with [a `satisfies never` check](https://www.typescriptlang.org/play?#code/C4TwDgpgBAYgTgVwJbCgXigcgIZjAGwkygB8sAjbAO2u0wG4AoRgMwSoGNgkB7KqBAGcI8ZMAAULRCgBcsacACUcwcDhIqAcygBvRlCiCA7ig4ALKJIWLd+g1A7ZhWXASJy99+3AjAEcfhw8QgApZA4iJi8AX2YvR2dMShoaTA87Lx8-AIpaGjCkCIYMqFiSgBMIFmwEfGB0rwMpMUNsbkEWJAhBKCoIADcIOCjGrP9A9gBrKh4jKgKikYNY5cZYoA).
|
|
31
|
+
|
|
32
|
+
### `requireDefaultForNonUnion`
|
|
33
|
+
|
|
34
|
+
Defaults to false. It set to true, this rule will also report when a `switch` statement switches over a non-union type (like a `number` or `string`, for example) and that `switch` statement does not have a `default` case. Thus, by setting this option to true, the rule becomes stricter.
|
|
35
|
+
|
|
36
|
+
This is generally desirable so that `number` and `string` switches will be subject to the same exhaustive checks that your other switches are.
|
|
37
|
+
|
|
38
|
+
Examples of additional **incorrect** code for this rule with `{ requireDefaultForNonUnion: true }`:
|
|
39
|
+
|
|
40
|
+
```ts option='{ "requireDefaultForNonUnion": true }' showPlaygroundButton
|
|
41
|
+
const value: number = Math.floor(Math.random() * 3);
|
|
42
|
+
|
|
43
|
+
switch (value) {
|
|
44
|
+
case 0:
|
|
45
|
+
return 0;
|
|
46
|
+
case 1:
|
|
47
|
+
return 1;
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Since `value` is a non-union type it requires the switch case to have a default clause only with `requireDefaultForNonUnion` enabled.
|
|
52
|
+
|
|
53
|
+
<!--/tabs-->
|
|
15
54
|
|
|
16
55
|
## Examples
|
|
17
56
|
|
|
@@ -181,27 +220,6 @@ switch (fruit) {
|
|
|
181
220
|
|
|
182
221
|
<!--/tabs-->
|
|
183
222
|
|
|
184
|
-
## Options
|
|
185
|
-
|
|
186
|
-
### `requireDefaultForNonUnion`
|
|
187
|
-
|
|
188
|
-
Examples of additional **incorrect** code for this rule with `{ requireDefaultForNonUnion: true }`:
|
|
189
|
-
|
|
190
|
-
```ts option='{ "requireDefaultForNonUnion": true }' showPlaygroundButton
|
|
191
|
-
const value: number = Math.floor(Math.random() * 3);
|
|
192
|
-
|
|
193
|
-
switch (value) {
|
|
194
|
-
case 0:
|
|
195
|
-
return 0;
|
|
196
|
-
case 1:
|
|
197
|
-
return 1;
|
|
198
|
-
}
|
|
199
|
-
```
|
|
200
|
-
|
|
201
|
-
Since `value` is a non-union type it requires the switch case to have a default clause only with `requireDefaultForNonUnion` enabled.
|
|
202
|
-
|
|
203
|
-
<!--/tabs-->
|
|
204
|
-
|
|
205
223
|
## When Not To Use It
|
|
206
224
|
|
|
207
225
|
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.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@typescript-eslint/eslint-plugin",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.17.0",
|
|
4
4
|
"description": "TypeScript plugin for ESLint",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist",
|
|
@@ -57,10 +57,10 @@
|
|
|
57
57
|
},
|
|
58
58
|
"dependencies": {
|
|
59
59
|
"@eslint-community/regexpp": "^4.5.1",
|
|
60
|
-
"@typescript-eslint/scope-manager": "6.
|
|
61
|
-
"@typescript-eslint/type-utils": "6.
|
|
62
|
-
"@typescript-eslint/utils": "6.
|
|
63
|
-
"@typescript-eslint/visitor-keys": "6.
|
|
60
|
+
"@typescript-eslint/scope-manager": "6.17.0",
|
|
61
|
+
"@typescript-eslint/type-utils": "6.17.0",
|
|
62
|
+
"@typescript-eslint/utils": "6.17.0",
|
|
63
|
+
"@typescript-eslint/visitor-keys": "6.17.0",
|
|
64
64
|
"debug": "^4.3.4",
|
|
65
65
|
"graphemer": "^1.4.0",
|
|
66
66
|
"ignore": "^5.2.4",
|
|
@@ -73,8 +73,8 @@
|
|
|
73
73
|
"@types/debug": "*",
|
|
74
74
|
"@types/marked": "*",
|
|
75
75
|
"@types/natural-compare": "*",
|
|
76
|
-
"@typescript-eslint/rule-schema-to-typescript-types": "6.
|
|
77
|
-
"@typescript-eslint/rule-tester": "6.
|
|
76
|
+
"@typescript-eslint/rule-schema-to-typescript-types": "6.17.0",
|
|
77
|
+
"@typescript-eslint/rule-tester": "6.17.0",
|
|
78
78
|
"ajv": "^6.12.6",
|
|
79
79
|
"chalk": "^5.3.0",
|
|
80
80
|
"cross-fetch": "*",
|
|
@@ -103,5 +103,5 @@
|
|
|
103
103
|
"type": "opencollective",
|
|
104
104
|
"url": "https://opencollective.com/typescript-eslint"
|
|
105
105
|
},
|
|
106
|
-
"gitHead": "
|
|
106
|
+
"gitHead": "e566a5dda347470b8ced3cc301b7e4d3e7ed721b"
|
|
107
107
|
}
|