@blumintinc/eslint-plugin-blumint 1.5.4 → 1.5.5
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/lib/index.js
CHANGED
|
@@ -87,12 +87,23 @@ function isInterfaceOrAbstractMethodSignature(node) {
|
|
|
87
87
|
}
|
|
88
88
|
return false;
|
|
89
89
|
}
|
|
90
|
+
function isTypeGuardFunction(node) {
|
|
91
|
+
if (!('returnType' in node) || !node.returnType)
|
|
92
|
+
return false;
|
|
93
|
+
const returnType = node.returnType;
|
|
94
|
+
if (returnType.type !== utils_1.AST_NODE_TYPES.TSTypeAnnotation)
|
|
95
|
+
return false;
|
|
96
|
+
const typeAnnotation = returnType.typeAnnotation;
|
|
97
|
+
if (typeAnnotation.type !== utils_1.AST_NODE_TYPES.TSTypePredicate)
|
|
98
|
+
return false;
|
|
99
|
+
return true;
|
|
100
|
+
}
|
|
90
101
|
exports.noExplicitReturnType = (0, createRule_1.createRule)({
|
|
91
102
|
name: 'no-explicit-return-type',
|
|
92
103
|
meta: {
|
|
93
104
|
type: 'suggestion',
|
|
94
105
|
docs: {
|
|
95
|
-
description: 'Disallow explicit return type annotations on functions when TypeScript can infer them. This reduces code verbosity and maintenance burden while leveraging TypeScript\'s powerful type inference. Exceptions are made for recursive functions, overloaded functions, interface methods, and abstract methods where explicit types improve clarity.',
|
|
106
|
+
description: 'Disallow explicit return type annotations on functions when TypeScript can infer them. This reduces code verbosity and maintenance burden while leveraging TypeScript\'s powerful type inference. Exceptions are made for type guard functions (using the `is` keyword), recursive functions, overloaded functions, interface methods, and abstract methods where explicit types improve clarity.',
|
|
96
107
|
recommended: 'error',
|
|
97
108
|
requiresTypeChecking: false,
|
|
98
109
|
extendsBaseRule: false,
|
|
@@ -136,8 +147,8 @@ exports.noExplicitReturnType = (0, createRule_1.createRule)({
|
|
|
136
147
|
FunctionDeclaration(node) {
|
|
137
148
|
if (!node.returnType)
|
|
138
149
|
return;
|
|
139
|
-
if (
|
|
140
|
-
isRecursiveFunction(node)) {
|
|
150
|
+
if (isTypeGuardFunction(node) ||
|
|
151
|
+
(mergedOptions.allowRecursiveFunctions && isRecursiveFunction(node))) {
|
|
141
152
|
return;
|
|
142
153
|
}
|
|
143
154
|
context.report({
|
|
@@ -149,8 +160,8 @@ exports.noExplicitReturnType = (0, createRule_1.createRule)({
|
|
|
149
160
|
FunctionExpression(node) {
|
|
150
161
|
if (!node.returnType)
|
|
151
162
|
return;
|
|
152
|
-
if (
|
|
153
|
-
isRecursiveFunction(node)) {
|
|
163
|
+
if (isTypeGuardFunction(node) ||
|
|
164
|
+
(mergedOptions.allowRecursiveFunctions && isRecursiveFunction(node))) {
|
|
154
165
|
return;
|
|
155
166
|
}
|
|
156
167
|
context.report({
|
|
@@ -162,6 +173,9 @@ exports.noExplicitReturnType = (0, createRule_1.createRule)({
|
|
|
162
173
|
ArrowFunctionExpression(node) {
|
|
163
174
|
if (!node.returnType)
|
|
164
175
|
return;
|
|
176
|
+
if (isTypeGuardFunction(node)) {
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
165
179
|
context.report({
|
|
166
180
|
node: node.returnType,
|
|
167
181
|
messageId: 'noExplicitReturnType',
|
|
@@ -39,9 +39,35 @@ exports.noUnusedProps = (0, createRule_1.createRule)({
|
|
|
39
39
|
typeNode.types.forEach(extractProps);
|
|
40
40
|
}
|
|
41
41
|
else if (typeNode.type === utils_1.AST_NODE_TYPES.TSTypeReference) {
|
|
42
|
-
// For referenced types like FormControlLabelProps, we need to track that these props should be forwarded
|
|
43
42
|
if (typeNode.typeName.type === utils_1.AST_NODE_TYPES.Identifier) {
|
|
44
|
-
|
|
43
|
+
if (typeNode.typeName.name === 'Pick' && typeNode.typeParameters) {
|
|
44
|
+
// Handle Pick utility type
|
|
45
|
+
const [baseType, pickedProps] = typeNode.typeParameters.params;
|
|
46
|
+
if (baseType.type === utils_1.AST_NODE_TYPES.TSTypeReference &&
|
|
47
|
+
baseType.typeName.type === utils_1.AST_NODE_TYPES.Identifier) {
|
|
48
|
+
// Extract the picked properties from the union type
|
|
49
|
+
if (pickedProps.type === utils_1.AST_NODE_TYPES.TSUnionType) {
|
|
50
|
+
pickedProps.types.forEach((type) => {
|
|
51
|
+
if (type.type === utils_1.AST_NODE_TYPES.TSLiteralType &&
|
|
52
|
+
type.literal.type === utils_1.AST_NODE_TYPES.Literal &&
|
|
53
|
+
typeof type.literal.value === 'string') {
|
|
54
|
+
// Add each picked property as a regular prop
|
|
55
|
+
props[type.literal.value] = type.literal;
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
else if (pickedProps.type === utils_1.AST_NODE_TYPES.TSLiteralType &&
|
|
60
|
+
pickedProps.literal.type === utils_1.AST_NODE_TYPES.Literal &&
|
|
61
|
+
typeof pickedProps.literal.value === 'string') {
|
|
62
|
+
// Single property pick
|
|
63
|
+
props[pickedProps.literal.value] = pickedProps.literal;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
// For referenced types like FormControlLabelProps, we need to track that these props should be forwarded
|
|
69
|
+
props[`...${typeNode.typeName.name}`] = typeNode.typeName;
|
|
70
|
+
}
|
|
45
71
|
}
|
|
46
72
|
}
|
|
47
73
|
}
|