Skip to content

Commit 0d750cb

Browse files
committed
support new defineEmits type syntax
1 parent 81783b7 commit 0d750cb

File tree

2 files changed

+67
-26
lines changed

2 files changed

+67
-26
lines changed

Diff for: lib/utils/ts-utils/ts-ast.js

+57-25
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ const { inferRuntimeTypeFromTypeNode } = require('./ts-types')
1111
*/
1212
/**
1313
* @typedef {import('../index').ComponentTypeProp} ComponentTypeProp
14+
* @typedef {import('../index').ComponentUnknownProp} ComponentUnknownProp
1415
* @typedef {import('../index').ComponentTypeEmit} ComponentTypeEmit
16+
* @typedef {import('../index').ComponentUnknownEmit} ComponentUnknownEmit
1517
*/
1618

1719
const noop = Function.prototype
@@ -122,57 +124,87 @@ function isTSTypeLiteralOrTSFunctionType(node) {
122124
* @see https://github.com/vuejs/vue-next/blob/253ca2729d808fc051215876aa4af986e4caa43c/packages/compiler-sfc/src/compileScript.ts#L1512
123125
* @param {RuleContext} context The ESLint rule context object.
124126
* @param {TSESTreeTSTypeLiteral | TSESTreeTSInterfaceBody} node
125-
* @returns {IterableIterator<ComponentTypeProp>}
127+
* @returns {IterableIterator<ComponentTypeProp | ComponentUnknownProp>}
126128
*/
127129
function* extractRuntimeProps(context, node) {
128130
const members = node.type === 'TSTypeLiteral' ? node.members : node.body
129-
for (const m of members) {
131+
for (const member of members) {
130132
if (
131-
(m.type === 'TSPropertySignature' || m.type === 'TSMethodSignature') &&
132-
(m.key.type === 'Identifier' || m.key.type === 'Literal')
133+
member.type === 'TSPropertySignature' ||
134+
member.type === 'TSMethodSignature'
133135
) {
136+
if (member.key.type !== 'Identifier' && member.key.type !== 'Literal') {
137+
yield {
138+
type: 'unknown',
139+
propName: null,
140+
node: /** @type {Expression} */ (member.key)
141+
}
142+
continue
143+
}
134144
/** @type {string[]|undefined} */
135145
let types
136-
if (m.type === 'TSMethodSignature') {
146+
if (member.type === 'TSMethodSignature') {
137147
types = ['Function']
138-
} else if (m.typeAnnotation) {
139-
types = inferRuntimeType(context, m.typeAnnotation.typeAnnotation)
148+
} else if (member.typeAnnotation) {
149+
types = inferRuntimeType(context, member.typeAnnotation.typeAnnotation)
140150
}
141151
yield {
142152
type: 'type',
143-
key: /** @type {Identifier | Literal} */ (m.key),
144-
propName: m.key.type === 'Identifier' ? m.key.name : `${m.key.value}`,
145-
node: /** @type {TSPropertySignature | TSMethodSignature} */ (m),
153+
key: /** @type {Identifier | Literal} */ (member.key),
154+
propName:
155+
member.key.type === 'Identifier'
156+
? member.key.name
157+
: `${member.key.value}`,
158+
node: /** @type {TSPropertySignature | TSMethodSignature} */ (member),
146159

147-
required: !m.optional,
160+
required: !member.optional,
148161
types: types || [`null`]
149162
}
150163
}
151164
}
152165
}
153166

154167
/**
155-
* @see https://github.com/vuejs/vue-next/blob/348c3b01e56383ffa70b180d1376fdf4ac12e274/packages/compiler-sfc/src/compileScript.ts#L1632
156168
* @param {TSESTreeTSTypeLiteral | TSESTreeTSInterfaceBody | TSESTreeTSFunctionType} node
157-
* @returns {IterableIterator<ComponentTypeEmit>}
169+
* @returns {IterableIterator<ComponentTypeEmit | ComponentUnknownEmit>}
158170
*/
159171
function* extractRuntimeEmits(node) {
160-
if (node.type === 'TSTypeLiteral' || node.type === 'TSInterfaceBody') {
161-
const members = node.type === 'TSTypeLiteral' ? node.members : node.body
162-
for (const t of members) {
163-
if (t.type === 'TSCallSignatureDeclaration') {
164-
yield* extractEventNames(
165-
t.params[0],
166-
/** @type {TSCallSignatureDeclaration} */ (t)
167-
)
168-
}
169-
}
170-
return
171-
} else {
172+
if (node.type === 'TSFunctionType') {
172173
yield* extractEventNames(
173174
node.params[0],
174175
/** @type {TSFunctionType} */ (node)
175176
)
177+
return
178+
}
179+
const members = node.type === 'TSTypeLiteral' ? node.members : node.body
180+
for (const member of members) {
181+
if (member.type === 'TSCallSignatureDeclaration') {
182+
yield* extractEventNames(
183+
member.params[0],
184+
/** @type {TSCallSignatureDeclaration} */ (member)
185+
)
186+
} else if (
187+
member.type === 'TSPropertySignature' ||
188+
member.type === 'TSMethodSignature'
189+
) {
190+
if (member.key.type !== 'Identifier' && member.key.type !== 'Literal') {
191+
yield {
192+
type: 'unknown',
193+
emitName: null,
194+
node: /** @type {Expression} */ (member.key)
195+
}
196+
continue
197+
}
198+
yield {
199+
type: 'type',
200+
key: /** @type {Identifier | Literal} */ (member.key),
201+
emitName:
202+
member.key.type === 'Identifier'
203+
? member.key.name
204+
: `${member.key.value}`,
205+
node: /** @type {TSPropertySignature | TSMethodSignature} */ (member)
206+
}
207+
}
176208
}
177209
}
178210

Diff for: typings/eslint-plugin-vue/util-types/utils.ts

+10-1
Original file line numberDiff line numberDiff line change
@@ -153,12 +153,21 @@ export type ComponentUnknownEmit = {
153153
node: Expression | SpreadElement | TypeNode | null
154154
}
155155

156-
export type ComponentTypeEmit = {
156+
export type ComponentTypeEmitCallSignature = {
157157
type: 'type'
158158
key: TSLiteralType
159159
emitName: string
160160
node: TSCallSignatureDeclaration | TSFunctionType
161161
}
162+
export type ComponentTypeEmitPropertySignature = {
163+
type: 'type'
164+
key: Identifier | Literal
165+
emitName: string
166+
node: TSPropertySignature | TSMethodSignature
167+
}
168+
export type ComponentTypeEmit =
169+
| ComponentTypeEmitCallSignature
170+
| ComponentTypeEmitPropertySignature
162171

163172
export type ComponentInferTypeEmit = {
164173
type: 'infer-type'

0 commit comments

Comments
 (0)