})
})
+ test('runtime inference for Enum in defineProps', () => {
+ expect(
+ compile(
+ `<script setup lang="ts">
+ const enum Foo { A = 123 }
+ defineProps<{
+ foo: Foo
+ }>()
+ </script>`,
+ { hoistStatic: true }
+ ).content
+ ).toMatch(`foo: { type: Number`)
+
+ expect(
+ compile(
+ `<script setup lang="ts">
+ const enum Foo { A = '123' }
+ defineProps<{
+ foo: Foo
+ }>()
+ </script>`,
+ { hoistStatic: true }
+ ).content
+ ).toMatch(`foo: { type: String`)
+
+ expect(
+ compile(
+ `<script setup lang="ts">
+ const enum Foo { A = '123', B = 123 }
+ defineProps<{
+ foo: Foo
+ }>()
+ </script>`,
+ { hoistStatic: true }
+ ).content
+ ).toMatch(`foo: { type: [String, Number]`)
+
+ expect(
+ compile(
+ `<script setup lang="ts">
+ const enum Foo { A, B }
+ defineProps<{
+ foo: Foo
+ }>()
+ </script>`,
+ { hoistStatic: true }
+ ).content
+ ).toMatch(`foo: { type: Number`)
+ })
+
test('import type', () => {
const { content } = compile(
`<script setup lang="ts">
ObjectMethod,
LVal,
Expression,
- VariableDeclaration
+ VariableDeclaration,
+ TSEnumDeclaration
} from '@babel/types'
import { walk } from 'estree-walker'
import { RawSourceMap } from 'source-map'
if (isTS) {
// move all Type declarations to outer scope
if (
- (node.type.startsWith('TS') ||
- (node.type === 'ExportNamedDeclaration' &&
- node.exportKind === 'type') ||
- (node.type === 'VariableDeclaration' && node.declare)) &&
- node.type !== 'TSEnumDeclaration'
+ node.type.startsWith('TS') ||
+ (node.type === 'ExportNamedDeclaration' &&
+ node.exportKind === 'type') ||
+ (node.type === 'VariableDeclaration' && node.declare)
) {
recordType(node, declaredTypes)
- hoistNode(node)
+ if (node.type !== 'TSEnumDeclaration') {
+ hoistNode(node)
+ }
}
}
}
)
} else if (node.type === 'ExportNamedDeclaration' && node.declaration) {
recordType(node.declaration, declaredTypes)
+ } else if (node.type === 'TSEnumDeclaration') {
+ declaredTypes[node.id.name] = inferEnumType(node)
}
}
return types.length > 1 ? `[${types.join(', ')}]` : types[0]
}
+function inferEnumType(node: TSEnumDeclaration): string[] {
+ const types = new Set<string>()
+ for (const m of node.members) {
+ if (m.initializer) {
+ switch (m.initializer.type) {
+ case 'StringLiteral':
+ types.add('String')
+ break
+ case 'NumericLiteral':
+ types.add('Number')
+ break
+ }
+ }
+ }
+ return types.size ? [...types] : ['Number']
+}
+
function extractRuntimeEmits(
node: TSFunctionType | TSTypeLiteral | TSInterfaceBody,
emits: Set<string>