diff --git a/lib/rules/require-typed-object-prop.js b/lib/rules/require-typed-object-prop.js
index ee88a0f35..eb7a278ae 100644
--- a/lib/rules/require-typed-object-prop.js
+++ b/lib/rules/require-typed-object-prop.js
@@ -129,6 +129,30 @@ module.exports = {
},
/** @param {RuleContext} context */
create(context) {
+ const filename = context.getFilename()
+ if (!utils.isVueFile(filename) && !utils.isTypeScriptFile(filename)) {
+ return {}
+ }
+
+ if (utils.isVueFile(filename)) {
+ const sourceCode = context.getSourceCode()
+ const documentFragment =
+ sourceCode.parserServices.getDocumentFragment &&
+ sourceCode.parserServices.getDocumentFragment()
+ if (!documentFragment) {
+ return {}
+ }
+ const scripts = documentFragment.children.filter(
+ /** @returns {element is VElement} */
+ (element) => utils.isVElement(element) && element.name === 'script'
+ )
+ if (
+ scripts.every((script) => !utils.hasAttribute(script, 'lang', 'ts'))
+ ) {
+ return {}
+ }
+ }
+
return utils.compositingVisitors(
utils.defineScriptSetupVisitor(context, {
onDefinePropsEnter(_node, props) {
diff --git a/tests/lib/rules/require-typed-object-prop.js b/tests/lib/rules/require-typed-object-prop.js
index 9f5f000a9..8a16fb567 100644
--- a/tests/lib/rules/require-typed-object-prop.js
+++ b/tests/lib/rules/require-typed-object-prop.js
@@ -9,7 +9,12 @@ const rule = require('../../../lib/rules/require-typed-object-prop')
const ruleTester = new RuleTester({
languageOptions: {
- parser: require('@typescript-eslint/parser')
+ parser: require('vue-eslint-parser'),
+ ecmaVersion: 6,
+ sourceType: 'module',
+ parserOptions: {
+ parser: require.resolve('@typescript-eslint/parser')
+ }
}
})
@@ -19,20 +24,22 @@ ruleTester.run('require-typed-object-prop', rule, {
{
filename: 'test.vue',
code: `
+
+ `
},
{
filename: 'test.vue',
code: `
+
+ `
},
{
filename: 'test.vue',
@@ -40,31 +47,28 @@ ruleTester.run('require-typed-object-prop', rule, {
- `,
- languageOptions: {
- parser: require('vue-eslint-parser'),
- ecmaVersion: 6,
- sourceType: 'module'
- }
+ `
},
// array props
{
filename: 'test.vue',
code: `
+
+ `
},
{
filename: 'test.vue',
code: `
+
+ `
},
{
filename: 'test.vue',
@@ -72,31 +76,28 @@ ruleTester.run('require-typed-object-prop', rule, {
- `,
- languageOptions: {
- parser: require('vue-eslint-parser'),
- ecmaVersion: 6,
- sourceType: 'module'
- }
+ `
},
// primitive props
{
filename: 'test.vue',
code: `
+
+ `
},
{
filename: 'test.vue',
code: `
+
+ `
},
{
filename: 'test.vue',
@@ -104,31 +105,28 @@ ruleTester.run('require-typed-object-prop', rule, {
- `,
- languageOptions: {
- parser: require('vue-eslint-parser'),
- ecmaVersion: 6,
- sourceType: 'module'
- }
+ `
},
// union
{
filename: 'test.vue',
code: `
+
+ `
},
{
filename: 'test.vue',
code: `
+
+ `
},
{
filename: 'test.vue',
@@ -136,31 +134,28 @@ ruleTester.run('require-typed-object-prop', rule, {
- `,
- languageOptions: {
- parser: require('vue-eslint-parser'),
- ecmaVersion: 6,
- sourceType: 'module'
- }
+ `
},
// function
{
filename: 'test.vue',
code: `
+
+ `
},
{
filename: 'test.vue',
code: `
+
+ `
},
{
filename: 'test.vue',
@@ -168,40 +163,38 @@ ruleTester.run('require-typed-object-prop', rule, {
- `,
- languageOptions: {
- parser: require('vue-eslint-parser'),
- ecmaVersion: 6,
- sourceType: 'module'
- }
+ `
},
// typed object
{
filename: 'test.vue',
code: `
+
+ `
},
{
filename: 'test.vue',
code: `
+
+ `
},
{
filename: 'test.vue',
code: `
+
+ `
},
{
filename: 'test.vue',
@@ -209,42 +202,28 @@ ruleTester.run('require-typed-object-prop', rule, {
- `,
- languageOptions: {
- parser: require('vue-eslint-parser'),
- ecmaVersion: 6,
- sourceType: 'module',
- parserOptions: {
- parser: require.resolve('@typescript-eslint/parser')
- }
- }
+ `
},
{
filename: 'test.vue',
code: `
+
+ `
},
{
filename: 'test.vue',
code: `
+
+ `
},
{
filename: 'test.vue',
@@ -252,15 +231,7 @@ ruleTester.run('require-typed-object-prop', rule, {
- `,
- languageOptions: {
- parser: require('vue-eslint-parser'),
- ecmaVersion: 6,
- sourceType: 'module',
- parserOptions: {
- parser: require.resolve('@typescript-eslint/parser')
- }
- }
+ `
},
// any
{
@@ -269,15 +240,7 @@ ruleTester.run('require-typed-object-prop', rule, {
- `,
- languageOptions: {
- parser: require('vue-eslint-parser'),
- ecmaVersion: 6,
- sourceType: 'module',
- parserOptions: {
- parser: require.resolve('@typescript-eslint/parser')
- }
- }
+ `
},
{
filename: 'test.vue',
@@ -289,15 +252,7 @@ ruleTester.run('require-typed-object-prop', rule, {
}
};
- `,
- languageOptions: {
- parser: require('vue-eslint-parser'),
- ecmaVersion: 6,
- sourceType: 'module',
- parserOptions: {
- parser: require.resolve('@typescript-eslint/parser')
- }
- }
+ `
},
{
filename: 'test.vue',
@@ -309,13 +264,7 @@ ruleTester.run('require-typed-object-prop', rule, {
}
});
- `,
- languageOptions: {
- parser: require('vue-eslint-parser'),
- ecmaVersion: 6,
- sourceType: 'module',
- parserOptions: { parser: require.resolve('@typescript-eslint/parser') }
- }
+ `
},
// unknown
{
@@ -324,13 +273,7 @@ ruleTester.run('require-typed-object-prop', rule, {
- `,
- languageOptions: {
- parser: require('vue-eslint-parser'),
- ecmaVersion: 6,
- sourceType: 'module',
- parserOptions: { parser: require.resolve('@typescript-eslint/parser') }
- }
+ `
},
{
filename: 'test.vue',
@@ -342,13 +285,7 @@ ruleTester.run('require-typed-object-prop', rule, {
}
};
- `,
- languageOptions: {
- parser: require('vue-eslint-parser'),
- ecmaVersion: 6,
- sourceType: 'module',
- parserOptions: { parser: require.resolve('@typescript-eslint/parser') }
- }
+ `
},
{
filename: 'test.vue',
@@ -360,13 +297,34 @@ ruleTester.run('require-typed-object-prop', rule, {
}
});
- `,
- languageOptions: {
- parser: require('vue-eslint-parser'),
- ecmaVersion: 6,
- sourceType: 'module',
- parserOptions: { parser: require.resolve('@typescript-eslint/parser') }
- }
+ `
+ },
+ // JavaScript components
+ {
+ filename: 'test.vue',
+ code: `
+
+ `
+ },
+ {
+ filename: 'test.vue',
+ code: `
+
+ `
+ },
+ {
+ filename: 'test.js',
+ code: `
+ export default Vue.extend({
+ props: { foo: Object }
+ });
+ `
}
],
invalid: [
@@ -377,14 +335,6 @@ ruleTester.run('require-typed-object-prop', rule, {
defineProps({ foo: Object });
`,
- languageOptions: {
- parser: require('vue-eslint-parser'),
- ecmaVersion: 6,
- sourceType: 'module',
- parserOptions: {
- parser: require.resolve('@typescript-eslint/parser')
- }
- },
errors: [
{
messageId: 'expectedTypeAnnotation',
@@ -422,14 +372,6 @@ ruleTester.run('require-typed-object-prop', rule, {
defineProps({ foo: Array });
`,
- languageOptions: {
- parser: require('vue-eslint-parser'),
- ecmaVersion: 6,
- sourceType: 'module',
- parserOptions: {
- parser: require.resolve('@typescript-eslint/parser')
- }
- },
errors: [
{
messageId: 'expectedTypeAnnotation',
@@ -463,35 +405,40 @@ ruleTester.run('require-typed-object-prop', rule, {
{
filename: 'test.vue',
code: `
+
`,
- languageOptions: { ecmaVersion: 6, sourceType: 'module' },
errors: [
{
messageId: 'expectedTypeAnnotation',
- line: 3,
+ line: 4,
column: 23,
- endLine: 3,
+ endLine: 4,
endColumn: 29,
suggestions: [
{
messageId: 'addTypeAnnotation',
data: { type: 'any' },
output: `
+
`
},
{
messageId: 'addTypeAnnotation',
data: { type: 'unknown' },
output: `
+
`
}
]
@@ -501,35 +448,40 @@ ruleTester.run('require-typed-object-prop', rule, {
{
filename: 'test.vue',
code: `
+
`,
- languageOptions: { ecmaVersion: 6, sourceType: 'module' },
errors: [
{
messageId: 'expectedTypeAnnotation',
- line: 3,
+ line: 4,
column: 23,
- endLine: 3,
+ endLine: 4,
endColumn: 29,
suggestions: [
{
messageId: 'addTypeAnnotation',
data: { type: 'any' },
output: `
+
`
},
{
messageId: 'addTypeAnnotation',
data: { type: 'unknown' },
output: `
+
`
}
]
@@ -539,35 +491,40 @@ ruleTester.run('require-typed-object-prop', rule, {
{
filename: 'test.vue',
code: `
+
`,
- languageOptions: { ecmaVersion: 6, sourceType: 'module' },
errors: [
{
messageId: 'expectedTypeAnnotation',
- line: 3,
+ line: 4,
column: 31,
- endLine: 3,
+ endLine: 4,
endColumn: 37,
suggestions: [
{
messageId: 'addTypeAnnotation',
data: { type: 'any' },
output: `
+
`
},
{
messageId: 'addTypeAnnotation',
data: { type: 'unknown' },
output: `
+
`
}
]
@@ -577,35 +534,40 @@ ruleTester.run('require-typed-object-prop', rule, {
{
filename: 'test.vue',
code: `
+
`,
- languageOptions: { ecmaVersion: 6, sourceType: 'module' },
errors: [
{
messageId: 'expectedTypeAnnotation',
- line: 3,
+ line: 4,
column: 31,
- endLine: 3,
+ endLine: 4,
endColumn: 37,
suggestions: [
{
messageId: 'addTypeAnnotation',
data: { type: 'any' },
output: `
+
`
},
{
messageId: 'addTypeAnnotation',
data: { type: 'unknown' },
output: `
+
`
}
]
@@ -619,14 +581,6 @@ ruleTester.run('require-typed-object-prop', rule, {
defineProps({ foo: { type: Object } });
`,
- languageOptions: {
- parser: require('vue-eslint-parser'),
- ecmaVersion: 6,
- sourceType: 'module',
- parserOptions: {
- parser: require.resolve('@typescript-eslint/parser')
- }
- },
errors: [
{
messageId: 'expectedTypeAnnotation',
@@ -656,6 +610,44 @@ ruleTester.run('require-typed-object-prop', rule, {
]
}
]
+ },
+ {
+ // `.ts` file
+ filename: 'test.ts',
+ code: `
+ export default Vue.extend({
+ props: { foo: Object }
+ });
+ `,
+ errors: [
+ {
+ messageId: 'expectedTypeAnnotation',
+ line: 3,
+ column: 23,
+ endLine: 3,
+ endColumn: 29,
+ suggestions: [
+ {
+ messageId: 'addTypeAnnotation',
+ data: { type: 'any' },
+ output: `
+ export default Vue.extend({
+ props: { foo: Object as PropType }
+ });
+ `
+ },
+ {
+ messageId: 'addTypeAnnotation',
+ data: { type: 'unknown' },
+ output: `
+ export default Vue.extend({
+ props: { foo: Object as PropType }
+ });
+ `
+ }
+ ]
+ }
+ ]
}
]
})