Skip to content

Commit 9fe8b34

Browse files
authored
Fix crash for TSFunctionType with type-literal option in vue/define-emits-declaration rule (#2336)
1 parent 73ee48f commit 9fe8b34

File tree

3 files changed

+53
-21
lines changed

3 files changed

+53
-21
lines changed

lib/rules/define-emits-declaration.js

+32-19
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
const utils = require('../utils')
88

99
/**
10-
* @typedef {import('@typescript-eslint/types').TSESTree.TSTypeLiteral} TSTypeLiteral
10+
* @typedef {import('@typescript-eslint/types').TSESTree.TypeNode} TypeNode
1111
*
1212
*/
1313

@@ -54,24 +54,7 @@ module.exports = {
5454
}
5555

5656
case 'type-literal': {
57-
if (node.arguments.length > 0) {
58-
context.report({
59-
node,
60-
messageId: 'hasArg'
61-
})
62-
return
63-
}
64-
65-
const typeArguments = node.typeArguments || node.typeParameters
66-
const param = /** @type {TSTypeLiteral} */ (typeArguments.params[0])
67-
for (const memberNode of param.members) {
68-
if (memberNode.type !== 'TSPropertySignature') {
69-
context.report({
70-
node: memberNode,
71-
messageId: 'hasTypeCallArg'
72-
})
73-
}
74-
}
57+
verifyTypeLiteral(node)
7558
break
7659
}
7760

@@ -89,5 +72,35 @@ module.exports = {
8972
}
9073
}
9174
})
75+
76+
/** @param {CallExpression} node */
77+
function verifyTypeLiteral(node) {
78+
if (node.arguments.length > 0) {
79+
context.report({
80+
node,
81+
messageId: 'hasArg'
82+
})
83+
return
84+
}
85+
86+
const typeArguments = node.typeArguments || node.typeParameters
87+
const param = /** @type {TypeNode|undefined} */ (typeArguments?.params[0])
88+
if (!param) return
89+
if (param.type === 'TSTypeLiteral') {
90+
for (const memberNode of param.members) {
91+
if (memberNode.type !== 'TSPropertySignature') {
92+
context.report({
93+
node: memberNode,
94+
messageId: 'hasTypeCallArg'
95+
})
96+
}
97+
}
98+
} else if (param.type === 'TSFunctionType') {
99+
context.report({
100+
node: param,
101+
messageId: 'hasTypeCallArg'
102+
})
103+
}
104+
}
92105
}
93106
}

tests/lib/rules/define-emits-declaration.js

+19
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,25 @@ tester.run('define-emits-declaration', rule, {
243243
line: 5
244244
}
245245
]
246+
},
247+
{
248+
filename: 'test.vue',
249+
code: `
250+
<script setup lang="ts">
251+
const emit = defineEmits<(e: 'change', id: number) => void>()
252+
</script>
253+
`,
254+
options: ['type-literal'],
255+
parserOptions: {
256+
parser: require.resolve('@typescript-eslint/parser')
257+
},
258+
errors: [
259+
{
260+
message:
261+
'Use new type literal declaration instead of the old call signature declaration.',
262+
line: 3
263+
}
264+
]
246265
}
247266
]
248267
})

typings/eslint-plugin-vue/util-types/ast/es-ast.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -522,7 +522,7 @@ export interface CallExpression extends HasParentNode {
522522
typeArguments?: TS.TSTypeParameterInstantiation
523523

524524
/* @deprecated */
525-
typeParameters: never
525+
typeParameters?: never
526526
}
527527
export interface Super extends HasParentNode {
528528
type: 'Super'
@@ -534,7 +534,7 @@ export interface NewExpression extends HasParentNode {
534534
typeArguments?: TSTypeParameterInstantiation
535535

536536
/* @deprecated */
537-
typeParameters: never
537+
typeParameters?: never
538538
}
539539
interface BaseMemberExpression extends HasParentNode {
540540
type: 'MemberExpression'

0 commit comments

Comments
 (0)