@@ -5,6 +5,7 @@ type Options = [
5
5
{
6
6
allowExpressions ?: boolean ;
7
7
allowTypedFunctionExpressions ?: boolean ;
8
+ allowUntypedSetters ?: boolean ;
8
9
}
9
10
] ;
10
11
type MessageIds = 'missingReturnType' ;
@@ -41,15 +42,17 @@ export default util.createRule<Options, MessageIds>({
41
42
{
42
43
allowExpressions : false ,
43
44
allowTypedFunctionExpressions : false ,
45
+ allowUntypedSetters : true ,
44
46
} ,
45
47
] ,
46
48
create ( context , [ options ] ) {
47
49
/**
48
50
* Checks if a node is a constructor.
49
51
* @param node The node to check
50
52
*/
51
- function isConstructor ( node : TSESTree . Node ) : boolean {
53
+ function isConstructor ( node : TSESTree . Node | undefined ) : boolean {
52
54
return (
55
+ ! ! node &&
53
56
node . type === AST_NODE_TYPES . MethodDefinition &&
54
57
node . kind === 'constructor'
55
58
) ;
@@ -58,14 +61,17 @@ export default util.createRule<Options, MessageIds>({
58
61
/**
59
62
* Checks if a node is a setter.
60
63
*/
61
- function isSetter ( node : TSESTree . Node ) : boolean {
64
+ function isSetter ( node : TSESTree . Node | undefined ) : boolean {
62
65
return (
63
- node . type === AST_NODE_TYPES . MethodDefinition && node . kind === 'set'
66
+ ! ! node &&
67
+ node . type === AST_NODE_TYPES . MethodDefinition &&
68
+ node . kind === 'set'
64
69
) ;
65
70
}
66
71
67
72
/**
68
73
* Checks if a node is a variable declarator with a type annotation.
74
+ * `const x: Foo = ...`
69
75
*/
70
76
function isVariableDeclaratorWithTypeAnnotation (
71
77
node : TSESTree . Node ,
@@ -76,41 +82,62 @@ export default util.createRule<Options, MessageIds>({
76
82
) ;
77
83
}
78
84
85
+ /**
86
+ * Checks if a node is a class property with a type annotation.
87
+ * `public x: Foo = ...`
88
+ */
89
+ function isClassPropertyWithTypeAnnotation ( node : TSESTree . Node ) : boolean {
90
+ return (
91
+ node . type === AST_NODE_TYPES . ClassProperty && ! ! node . typeAnnotation
92
+ ) ;
93
+ }
94
+
95
+ /**
96
+ * Checks if a node is a type cast
97
+ * `(() => {}) as Foo`
98
+ * `<Foo>(() => {})`
99
+ */
100
+ function isTypeCast ( node : TSESTree . Node ) : boolean {
101
+ return (
102
+ node . type === AST_NODE_TYPES . TSAsExpression ||
103
+ node . type === AST_NODE_TYPES . TSTypeAssertion
104
+ ) ;
105
+ }
106
+
79
107
/**
80
108
* Checks if a node belongs to:
81
- * const x: Foo = { prop: () => {} }
109
+ * `const x: Foo = { prop: () => {} }`
110
+ * `const x = { prop: () => {} } as Foo`
111
+ * `const x = <Foo>{ prop: () => {} }`
82
112
*/
83
- function isPropertyOfObjectVariableDeclaratorWithTypeAnnotation (
84
- node : TSESTree . Node ,
113
+ function isPropertyOfObjectWithType (
114
+ parent : TSESTree . Node | undefined ,
85
115
) : boolean {
86
- let parent = node . parent ;
87
116
if ( ! parent || parent . type !== AST_NODE_TYPES . Property ) {
88
117
return false ;
89
118
}
90
- parent = parent . parent ;
91
- if ( ! parent || parent . type !== AST_NODE_TYPES . ObjectExpression ) {
119
+ parent = parent . parent ; // this shouldn't happen, checking just in case
120
+ /*
10000
istanbul ignore if */ if (
121
+ ! parent ||
122
+ parent . type !== AST_NODE_TYPES . ObjectExpression
123
+ ) {
92
124
return false ;
93
125
}
94
- parent = parent . parent ;
95
- return ! ! parent && isVariableDeclaratorWithTypeAnnotation ( parent ) ;
96
- }
97
126
98
- function isPropertyOfObjectInAsExpression ( node : TSESTree . Node ) : boolean {
99
- let parent = node . parent ;
100
- if ( ! parent || parent . type !== AST_NODE_TYPES . Property ) {
127
+ parent = parent . parent ; // this shouldn't happen, checking just in case
128
+ /* istanbul ignore if */ if ( ! parent ) {
101
129
return false ;
102
130
}
103
- parent = parent . parent ;
104
- if ( ! parent || parent . type !== AST_NODE_TYPES . ObjectExpression ) {
105
- return false ;
106
- }
107
- parent = parent . parent ;
108
- return ! ! parent && parent . type === AST_NODE_TYPES . TSAsExpression ;
131
+
132
+ return (
133
+ isTypeCast ( parent ) ||
134
+ isClassPropertyWithTypeAnnotation ( parent ) ||
135
+ isVariableDeclaratorWithTypeAnnotation ( parent )
136
+ ) ;
109
137
}
110
138
111
139
/**
112
140
* Checks if a function declaration/expression has a return type.
113
- * @param node The node representing a function.
114
141
*/
115
142
function checkFunctionReturnType (
116
143
node :
@@ -119,22 +146,14 @@ export default util.createRule<Options, MessageIds>({
119
146
| TSESTree . FunctionExpression ,
120
147
) : void {
121
148
if (
122
- options . allowExpressions &&
123
- node . type !== AST_NODE_TYPES . FunctionDeclaration &&
124
- node . parent &&
125
- node . parent . type !== AST_NODE_TYPES . VariableDeclarator &&
126
- node . parent . type !== AST_NODE_TYPES . MethodDefinition
149
+ node . returnType ||
150
+ isConstructor ( node . parent ) ||
151
+ isSetter ( node . parent )
127
152
) {
128
153
return ;
129
154
}
130
155
131
- if (
132
- ! node . returnType &&
133
- node . parent &&
134
- ! isConstructor ( node . parent ) &&
135
- ! isSetter ( node . parent ) &&
136
- util . isTypeScriptFile ( context . getFilename ( ) )
137
- ) {
156
+ if ( util . isTypeScriptFile ( context . getFilename ( ) ) ) {
138
157
context . report ( {
139
158
node,
140
159
messageId : 'missingReturnType' ,
@@ -144,20 +163,29 @@ export default util.createRule<Options, MessageIds>({
144
163
145
164
/**
146
165
* Checks if a function declaration/expression has a return type.
147
- * @param {ASTNode } node The node representing a function.
148
166
*/
149
167
function checkFunctionExpressionReturnType (
150
168
node : TSESTree . ArrowFunctionExpression | TSESTree . FunctionExpression ,
151
169
) : void {
152
- if (
153
- options . allowTypedFunctionExpressions &&
154
- node . parent &&
155
- ( isVariableDeclaratorWithTypeAnnotation ( node . parent ) ||
156
- isPropertyOfObjectVariableDeclaratorWithTypeAnnotation ( node ) ||
157
- node . parent . type === AST_NODE_TYPES . TSAsExpression ||
158
- isPropertyOfObjectInAsExpression ( node ) )
159
- ) {
160
- return ;
170
+ if ( node . parent ) {
171
+ if ( options . allowTypedFunctionExpressions ) {
172
+ if (
173
+ isTypeCast ( node . parent ) ||
174
+ isVariableDeclaratorWithTypeAnnotation ( node . parent ) ||
175
+ isClassPropertyWithTypeAnnotation ( node . parent ) ||
176
+ isPropertyOfObjectWithType ( node . parent )
177
+ ) {
178
+ return ;
179
+ }
180
+ }
181
+
182
+ if (
183
+ options . allowExpressions &&
184
+ node . parent . type !== AST_NODE_TYPES . VariableDeclarator &&
185
+ node . parent . type !== AST_NODE_TYPES . MethodDefinition
186
+ ) {
187
+ return ;
188
+ }
161
189
}
162
190
163
191
checkFunctionReturnType ( node ) ;
0 commit comments