Skip to content

Commit

Permalink
feat(valid-v-model): add support for type assertions and non-null exp…
Browse files Browse the repository at this point in the history
…ressions (#2393)
  • Loading branch information
auvred committed Feb 22, 2024
1 parent 4ea3dfc commit 1e12806
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 0 deletions.
4 changes: 4 additions & 0 deletions lib/rules/valid-v-model.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ function isOptionalChainingMemberExpression(node) {
* @returns {boolean} `true` if the node can be LHS.
*/
function isLhs(node) {
if (node.type === 'TSAsExpression' || node.type === 'TSNonNullExpression') {
return isLhs(node.expression)
}

return node.type === 'Identifier' || node.type === 'MemberExpression'
}

Expand Down
105 changes: 105 additions & 0 deletions tests/lib/rules/valid-v-model.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,51 @@ tester.run('valid-v-model', rule, {
{
filename: 'comment-value.vue',
code: '<template><MyComponent v-model="/**/" /></template>'
},
{
filename: 'test.vue',
code: '<template><MyComponent v-model="a as string"></MyComponent></template>',
languageOptions: {
parserOptions: {
parser: require.resolve('@typescript-eslint/parser')
}
}
},
{
filename: 'test.vue',
code: '<template><MyComponent v-model="a!"></MyComponent></template>',
languageOptions: {
parserOptions: {
parser: require.resolve('@typescript-eslint/parser')
}
}
},
{
filename: 'test.vue',
code: '<template><MyComponent v-model="a as unknown as string"></MyComponent></template>',
languageOptions: {
parserOptions: {
parser: require.resolve('@typescript-eslint/parser')
}
}
},
{
filename: 'test.vue',
code: '<template><MyComponent v-model="a!!!!"></MyComponent></template>',
languageOptions: {
parserOptions: {
parser: require.resolve('@typescript-eslint/parser')
}
}
},
{
filename: 'test.vue',
code: '<template><MyComponent v-model="(((a!) as unknown)! as string)!"></MyComponent></template>',
languageOptions: {
parserOptions: {
parser: require.resolve('@typescript-eslint/parser')
}
}
}
],
invalid: [
Expand Down Expand Up @@ -241,6 +286,66 @@ tester.run('valid-v-model', rule, {
filename: 'test.vue',
code: '<template><input v-model="(a?.b).c.d"></template>',
errors: ["'v-model' directive has potential null object property access."]
},
{
filename: 'test.vue',
code: '<template><MyComponent v-model="a() as string"></MyComponent></template>',
errors: [
"'v-model' directives require the attribute value which is valid as LHS."
],
languageOptions: {
parserOptions: {
parser: require.resolve('@typescript-eslint/parser')
}
}
},
{
filename: 'test.vue',
code: '<template><MyComponent v-model="a()!"></MyComponent></template>',
errors: [
"'v-model' directives require the attribute value which is valid as LHS."
],
languageOptions: {
parserOptions: {
parser: require.resolve('@typescript-eslint/parser')
}
}
},
{
filename: 'test.vue',
code: '<template><MyComponent v-model="a() as unknown as string"></MyComponent></template>',
errors: [
"'v-model' directives require the attribute value which is valid as LHS."
],
languageOptions: {
parserOptions: {
parser: require.resolve('@typescript-eslint/parser')
}
}
},
{
filename: 'test.vue',
code: '<template><MyComponent v-model="a()!!!!"></MyComponent></template>',
errors: [
"'v-model' directives require the attribute value which is valid as LHS."
],
languageOptions: {
parserOptions: {
parser: require.resolve('@typescript-eslint/parser')
}
}
},
{
filename: 'test.vue',
code: '<template><MyComponent v-model="(((a()!) as unknown)! as string)!"></MyComponent></template>',
errors: [
"'v-model' directives require the attribute value which is valid as LHS."
],
languageOptions: {
parserOptions: {
parser: require.resolve('@typescript-eslint/parser')
}
}
}
]
})
6 changes: 6 additions & 0 deletions typings/eslint-plugin-vue/util-types/ast/ts-ast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import * as ES from './es-ast'
import { TSESTree } from '@typescript-eslint/types'
export type TSNode =
| TSAsExpression
| TSNonNullExpression
| TSTypeParameterInstantiation
| TSPropertySignature
| TSMethodSignatureBase
Expand All @@ -20,6 +21,11 @@ export interface TSAsExpression extends HasParentNode {
typeAnnotation: any
}

export interface TSNonNullExpression extends HasParentNode {
type: 'TSNonNullExpression'
expression: ES.Expression
}

export interface TSTypeParameterInstantiation extends HasParentNode {
type: 'TSTypeParameterInstantiation'
params: TypeNode[]
Expand Down

0 comments on commit 1e12806

Please sign in to comment.