chore: more case

This commit is contained in:
daiwei 2023-06-02 10:02:24 +08:00
parent 57467392e4
commit 6831c2f9ef
4 changed files with 57 additions and 11 deletions

View File

@ -16,13 +16,15 @@ return { myEmit }
exports[`defineEmits > w/ enum value 1`] = ` exports[`defineEmits > w/ enum value 1`] = `
"import { defineComponent as _defineComponent } from 'vue' "import { defineComponent as _defineComponent } from 'vue'
enum Foo { BAR = 'bar' } enum Foo { BAR = 'bar', BAZ = 'baz', QUX = 'qux' }
type BAZ = Foo.BAZ
interface Emits { interface Emits {
(e: Foo.BAR, value: string): void; (e: Foo.BAR, value: string): void;
(e: BAZ, value: string): void;
} }
export default /*#__PURE__*/_defineComponent({ export default /*#__PURE__*/_defineComponent({
emits: [\\"bar\\"], emits: [\\"bar\\", \\"baz\\"],
setup(__props, { expose: __expose, emit }) { setup(__props, { expose: __expose, emit }) {
__expose(); __expose();

View File

@ -92,15 +92,17 @@ const emit = defineEmits(['a', 'b'])
test('w/ enum value', () => { test('w/ enum value', () => {
const { content } = compile(` const { content } = compile(`
<script setup lang="ts"> <script setup lang="ts">
enum Foo { BAR = 'bar' } enum Foo { BAR = 'bar', BAZ = 'baz', QUX = 'qux' }
type BAZ = Foo.BAZ
interface Emits { interface Emits {
(e: Foo.BAR, value: string): void; (e: Foo.BAR, value: string): void;
(e: BAZ, value: string): void;
} }
const emit = defineEmits<Emits>() const emit = defineEmits<Emits>()
</script> </script>
`) `)
assertCode(content) assertCode(content)
expect(content).toMatch(`emits: ["bar"]`) expect(content).toMatch(`emits: ["bar", "baz"]`)
}) })
test('w/ type from normal script', () => { test('w/ type from normal script', () => {

View File

@ -1,7 +1,17 @@
import { Identifier, LVal, Node, RestElement } from '@babel/types' import {
Identifier,
LVal,
Node,
RestElement,
TSEnumDeclaration
} from '@babel/types'
import { isCallOf } from './utils' import { isCallOf } from './utils'
import { ScriptCompileContext } from './context' import { ScriptCompileContext } from './context'
import { resolveTypeElements, resolveUnionType } from './resolveType' import {
resolveTypeElements,
resolveUnionType,
resolveTypeReference
} from './resolveType'
export const DEFINE_EMITS = 'defineEmits' export const DEFINE_EMITS = 'defineEmits'
@ -102,7 +112,8 @@ function extractEventNames(
eventName.typeAnnotation && eventName.typeAnnotation &&
eventName.typeAnnotation.type === 'TSTypeAnnotation' eventName.typeAnnotation.type === 'TSTypeAnnotation'
) { ) {
const types = resolveUnionType(ctx, eventName.typeAnnotation.typeAnnotation) const typeNode = eventName.typeAnnotation.typeAnnotation
const types = resolveUnionType(ctx, typeNode)
for (const type of types) { for (const type of types) {
if (type.type === 'TSLiteralType') { if (type.type === 'TSLiteralType') {
@ -113,12 +124,43 @@ function extractEventNames(
emits.add(String(type.literal.value)) emits.add(String(type.literal.value))
} }
} else if (type.type === 'TSEnumDeclaration') { } else if (type.type === 'TSEnumDeclaration') {
for (const m of type.members) { if (typeNode.type === 'TSTypeReference') {
if (m.initializer && m.initializer.type === 'StringLiteral') { if (typeNode.typeName.type === 'TSQualifiedName') {
emits.add(String(m.initializer.value)) extractEnumValue(type, typeNode.typeName.right.name, emits)
}
}
} else if (type.type === 'TSTypeReference') {
if (
type.typeName.type === 'TSQualifiedName' &&
type.typeName.left.type === 'Identifier'
) {
const resolved = resolveTypeReference(
ctx,
type,
undefined,
type.typeName.left.name
)
if (resolved && resolved.type === 'TSEnumDeclaration') {
extractEnumValue(resolved, type.typeName.right.name, emits)
} }
} }
} }
} }
} }
} }
function extractEnumValue(
typeNode: TSEnumDeclaration,
typeName: string,
emits: Set<string>
) {
for (const m of typeNode.members) {
if (
m.id.type === 'Identifier' &&
m.id.name === typeName &&
m.initializer &&
m.initializer.type === 'StringLiteral'
) {
emits.add(String(m.initializer.value))
}
}
}

View File

@ -593,7 +593,7 @@ type ReferenceTypes =
| TSImportType | TSImportType
| TSTypeQuery | TSTypeQuery
function resolveTypeReference( export function resolveTypeReference(
ctx: TypeResolveContext, ctx: TypeResolveContext,
node: ReferenceTypes & { node: ReferenceTypes & {
_resolvedReference?: ScopeTypeNode _resolvedReference?: ScopeTypeNode