mirror of https://github.com/vuejs/core.git
feat(compiler-sfc): improve runtime props inference for enum
This commit is contained in:
parent
5fb406e3e1
commit
eded94712e
|
@ -1573,6 +1573,56 @@ const emit = defineEmits(['a', 'b'])
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
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', () => {
|
test('import type', () => {
|
||||||
const { content } = compile(
|
const { content } = compile(
|
||||||
`<script setup lang="ts">
|
`<script setup lang="ts">
|
||||||
|
|
|
@ -44,7 +44,8 @@ import {
|
||||||
ObjectMethod,
|
ObjectMethod,
|
||||||
LVal,
|
LVal,
|
||||||
Expression,
|
Expression,
|
||||||
VariableDeclaration
|
VariableDeclaration,
|
||||||
|
TSEnumDeclaration
|
||||||
} from '@babel/types'
|
} from '@babel/types'
|
||||||
import { walk } from 'estree-walker'
|
import { walk } from 'estree-walker'
|
||||||
import { RawSourceMap } from 'source-map'
|
import { RawSourceMap } from 'source-map'
|
||||||
|
@ -1369,17 +1370,18 @@ export function compileScript(
|
||||||
if (isTS) {
|
if (isTS) {
|
||||||
// move all Type declarations to outer scope
|
// move all Type declarations to outer scope
|
||||||
if (
|
if (
|
||||||
(node.type.startsWith('TS') ||
|
node.type.startsWith('TS') ||
|
||||||
(node.type === 'ExportNamedDeclaration' &&
|
(node.type === 'ExportNamedDeclaration' &&
|
||||||
node.exportKind === 'type') ||
|
node.exportKind === 'type') ||
|
||||||
(node.type === 'VariableDeclaration' && node.declare)) &&
|
(node.type === 'VariableDeclaration' && node.declare)
|
||||||
node.type !== 'TSEnumDeclaration'
|
|
||||||
) {
|
) {
|
||||||
recordType(node, declaredTypes)
|
recordType(node, declaredTypes)
|
||||||
|
if (node.type !== 'TSEnumDeclaration') {
|
||||||
hoistNode(node)
|
hoistNode(node)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 3. Apply reactivity transform
|
// 3. Apply reactivity transform
|
||||||
if (
|
if (
|
||||||
|
@ -1966,6 +1968,8 @@ function recordType(node: Node, declaredTypes: Record<string, string[]>) {
|
||||||
)
|
)
|
||||||
} else if (node.type === 'ExportNamedDeclaration' && node.declaration) {
|
} else if (node.type === 'ExportNamedDeclaration' && node.declaration) {
|
||||||
recordType(node.declaration, declaredTypes)
|
recordType(node.declaration, declaredTypes)
|
||||||
|
} else if (node.type === 'TSEnumDeclaration') {
|
||||||
|
declaredTypes[node.id.name] = inferEnumType(node)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2152,6 +2156,23 @@ function toRuntimeTypeString(types: string[]) {
|
||||||
return types.length > 1 ? `[${types.join(', ')}]` : types[0]
|
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(
|
function extractRuntimeEmits(
|
||||||
node: TSFunctionType | TSTypeLiteral | TSInterfaceBody,
|
node: TSFunctionType | TSTypeLiteral | TSInterfaceBody,
|
||||||
emits: Set<string>
|
emits: Set<string>
|
||||||
|
|
Loading…
Reference in New Issue