fix(compiler-sfc): enhance inferRuntimeType to support TSMappedType with indexed access (#13848)

close #13847
This commit is contained in:
edison 2025-09-24 17:29:38 +08:00 committed by GitHub
parent fda47ac702
commit e388f1a09f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 57 additions and 0 deletions

View File

@ -742,6 +742,22 @@ describe('resolveType', () => {
})
})
test('TSMappedType with indexed access', () => {
const { props } = resolve(
`
type Prettify<T> = { [K in keyof T]: T[K] } & {}
type Side = 'top' | 'right' | 'bottom' | 'left'
type AlignedPlacement = \`\${Side}-\${Alignment}\`
type Alignment = 'start' | 'end'
type Placement = Prettify<Side | AlignedPlacement>
defineProps<{placement?: Placement}>()
`,
)
expect(props).toStrictEqual({
placement: ['String', 'Object'],
})
})
describe('type alias declaration', () => {
// #13240
test('function type', () => {

View File

@ -1788,6 +1788,47 @@ export function inferRuntimeType(
typeParameters,
).filter(t => t !== UNKNOWN_TYPE)
}
case 'TSMappedType': {
// only support { [K in keyof T]: T[K] }
const { typeAnnotation, typeParameter } = node
if (
typeAnnotation &&
typeAnnotation.type === 'TSIndexedAccessType' &&
typeParameter &&
typeParameter.constraint &&
typeParameters
) {
const constraint = typeParameter.constraint
if (
constraint.type === 'TSTypeOperator' &&
constraint.operator === 'keyof' &&
constraint.typeAnnotation &&
constraint.typeAnnotation.type === 'TSTypeReference' &&
constraint.typeAnnotation.typeName.type === 'Identifier'
) {
const typeName = constraint.typeAnnotation.typeName.name
const index = typeAnnotation.indexType
const obj = typeAnnotation.objectType
if (
obj &&
obj.type === 'TSTypeReference' &&
obj.typeName.type === 'Identifier' &&
obj.typeName.name === typeName &&
index &&
index.type === 'TSTypeReference' &&
index.typeName.type === 'Identifier' &&
index.typeName.name === typeParameter.name
) {
const targetType = typeParameters[typeName]
if (targetType) {
return inferRuntimeType(ctx, targetType, scope)
}
}
}
}
return [UNKNOWN_TYPE]
}
case 'TSEnumDeclaration':
return inferEnumType(node)