Skip to content

Commit fe9a4f0

Browse files
rewrite force-types-on-object-props
1 parent 75fc825 commit fe9a4f0

File tree

2 files changed

+385
-93
lines changed

2 files changed

+385
-93
lines changed

lib/rules/force-types-on-object-props.js

+115
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@
44
*/
55
'use strict'
66

7+
const { type } = require('os')
8+
const utils = require('../utils')
9+
/**
10+
* @typedef {import('../utils').ComponentProp} ComponentProp
11+
*/
12+
713
// ------------------------------------------------------------------------------
814
// Helpers
915
// ------------------------------------------------------------------------------
@@ -29,6 +35,98 @@ const isLooksLike = (a, b) =>
2935
: isLooksLike(aVal, bVal)
3036
})
3137

38+
/**
39+
* @param {ComponentProp} property
40+
* @param {RuleContext} context
41+
*/
42+
const checkProperty = (property, context) => {
43+
console.log(property.node.value)
44+
if (!property.value) {
45+
return
46+
}
47+
48+
if (
49+
isLooksLike(property.value, { type: 'Identifier', name: 'Object' }) &&
50+
property.node.value.type !== 'TSAsExpression'
51+
) {
52+
context.report({
53+
node: property.node,
54+
message: 'Expected type annotation on object prop.'
55+
})
56+
}
57+
58+
if (
59+
property.type === 'object' &&
60+
property.value.type === 'ObjectExpression' &&
61+
property.node.value.type === 'ObjectExpression'
62+
) {
63+
const typePropert = property.node.value.properties.find(
64+
(prop) =>
65+
prop.type === 'Property' &&
66+
prop.key.type === 'Identifier' &&
67+
prop.key.name === 'type'
68+
)
69+
if (
70+
typePropert &&
71+
typePropert.type === 'Property' &&
72+
isLooksLike(typePropert.value, { type: 'Identifier', name: 'Object' })
73+
) {
74+
context.report({
75+
node: property.node,
76+
message: 'Expected type annotation on object prop.'
77+
})
78+
}
79+
}
80+
81+
if (property.node.value.type === 'ObjectExpression') {
82+
for (const prop of property.node.value.properties) {
83+
if (prop.type !== 'Property') {
84+
continue
85+
}
86+
if (prop.key.type !== 'Identifier' || prop.key.name !== 'type') {
87+
continue
88+
}
89+
if (prop.value.type !== 'TSAsExpression') {
90+
continue
91+
}
92+
93+
const { typeAnnotation } = prop.value
94+
if (
95+
['TSAnyKeyword', 'TSUnknownKeyword'].includes(typeAnnotation.type) ||
96+
!typeAnnotation.typeName ||
97+
!['Prop', 'PropType'].includes(typeAnnotation.typeName.name)
98+
) {
99+
context.report({
100+
node: property.node,
101+
message: 'Expected type annotation on object prop.'
102+
})
103+
}
104+
}
105+
}
106+
107+
if (property.node.value.type === 'TSAsExpression') {
108+
const { typeAnnotation } = property.node.value
109+
if (typeAnnotation.type === 'TSFunctionType') {
110+
return
111+
}
112+
if (
113+
[
114+
'TSAnyKeyword',
115+
'TSTypeLiteral',
116+
'TSUnknownKeyword',
117+
'TSObjectKeyword'
118+
].includes(typeAnnotation.type) ||
119+
!typeAnnotation.typeName ||
120+
!['Prop', 'PropType'].includes(typeAnnotation.typeName.name)
121+
) {
122+
context.report({
123+
node: property.node,
124+
message: 'Expected type annotation on object prop.'
125+
})
126+
}
127+
}
128+
}
129+
32130
//------------------------------------------------------------------------------
33131
// Rule Definition
34132
//------------------------------------------------------------------------------
@@ -47,6 +145,23 @@ module.exports = {
47145
},
48146
/** @param {RuleContext} context */
49147
create(context) {
148+
return utils.compositingVisitors(
149+
utils.defineScriptSetupVisitor(context, {
150+
onDefinePropsEnter(_node, props) {
151+
for (const prop of props) {
152+
checkProperty(prop, context)
153+
}
154+
}
155+
}),
156+
utils.executeOnVue(context, (obj) => {
157+
const props = utils.getComponentPropsFromOptions(obj)
158+
159+
for (const prop of props) {
160+
checkProperty(prop, context)
161+
}
162+
})
163+
)
164+
50165
return {
51166
/** @param {ExportDefaultDeclaration} node */
52167
ExportDefaultDeclaration(node) {

0 commit comments

Comments
 (0)