fix(compiler-sfc): infer correct type for enums

fix #7511
This commit is contained in:
Evan You 2023-03-28 16:39:13 +08:00
parent 0002567728
commit 2e074a7009
3 changed files with 22 additions and 9 deletions

View File

@ -1677,6 +1677,8 @@ interface Test {}
type Alias = number[] type Alias = number[]
enum Enum { one = '1', two = '2' }
export default /*#__PURE__*/_defineComponent({ export default /*#__PURE__*/_defineComponent({
props: { props: {
@ -1702,6 +1704,7 @@ export default /*#__PURE__*/_defineComponent({
symbol: { type: Symbol, required: true }, symbol: { type: Symbol, required: true },
extract: { type: Number, required: true }, extract: { type: Number, required: true },
exclude: { type: [Number, Boolean], required: true }, exclude: { type: [Number, Boolean], required: true },
enum: { type: Object, required: true },
uppercase: { type: String, required: true }, uppercase: { type: String, required: true },
params: { type: Array, required: true }, params: { type: Array, required: true },
nonNull: { type: String, required: true }, nonNull: { type: String, required: true },
@ -1719,7 +1722,7 @@ export default /*#__PURE__*/_defineComponent({
return { } return { Enum }
} }
})" })"

View File

@ -998,6 +998,8 @@ const emit = defineEmits(['a', 'b'])
type Alias = number[] type Alias = number[]
enum Enum { one = '1', two = '2' }
defineProps<{ defineProps<{
string: string string: string
number: number number: number
@ -1021,6 +1023,7 @@ const emit = defineEmits(['a', 'b'])
symbol: symbol symbol: symbol
extract: Extract<1 | 2 | boolean, 2> extract: Extract<1 | 2 | boolean, 2>
exclude: Exclude<1 | 2 | boolean, 2> exclude: Exclude<1 | 2 | boolean, 2>
enum: Enum
uppercase: Uppercase<'foo'> uppercase: Uppercase<'foo'>
params: Parameters<(foo: any) => void> params: Parameters<(foo: any) => void>
nonNull: NonNullable<string | null> nonNull: NonNullable<string | null>
@ -1066,6 +1069,7 @@ const emit = defineEmits(['a', 'b'])
expect(content).toMatch( expect(content).toMatch(
`exclude: { type: [Number, Boolean], required: true }` `exclude: { type: [Number, Boolean], required: true }`
) )
expect(content).toMatch(`enum: { type: Object, required: true }`)
expect(content).toMatch(`uppercase: { type: String, required: true }`) expect(content).toMatch(`uppercase: { type: String, required: true }`)
expect(content).toMatch(`params: { type: Array, required: true }`) expect(content).toMatch(`params: { type: Array, required: true }`)
expect(content).toMatch(`nonNull: { type: String, required: true }`) expect(content).toMatch(`nonNull: { type: String, required: true }`)
@ -1115,7 +1119,9 @@ const emit = defineEmits(['a', 'b'])
foo: BindingTypes.PROPS, foo: BindingTypes.PROPS,
uppercase: BindingTypes.PROPS, uppercase: BindingTypes.PROPS,
params: BindingTypes.PROPS, params: BindingTypes.PROPS,
nonNull: BindingTypes.PROPS nonNull: BindingTypes.PROPS,
enum: BindingTypes.PROPS,
Enum: BindingTypes.LITERAL_CONST
}) })
}) })

View File

@ -1369,17 +1369,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 (
@ -1957,7 +1958,10 @@ interface PropTypeData {
} }
function recordType(node: Node, declaredTypes: Record<string, string[]>) { function recordType(node: Node, declaredTypes: Record<string, string[]>) {
if (node.type === 'TSInterfaceDeclaration') { if (
node.type === 'TSInterfaceDeclaration' ||
node.type === 'TSEnumDeclaration'
) {
declaredTypes[node.id.name] = [`Object`] declaredTypes[node.id.name] = [`Object`]
} else if (node.type === 'TSTypeAliasDeclaration') { } else if (node.type === 'TSTypeAliasDeclaration') {
declaredTypes[node.id.name] = inferRuntimeType( declaredTypes[node.id.name] = inferRuntimeType(