Skip to content

Commit e388f1a

Browse files
authored
fix(compiler-sfc): enhance inferRuntimeType to support TSMappedType with indexed access (#13848)
close #13847
1 parent fda47ac commit e388f1a

File tree

2 files changed

+57
-0
lines changed

2 files changed

+57
-0
lines changed

packages/compiler-sfc/__tests__/compileScript/resolveType.spec.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -742,6 +742,22 @@ describe('resolveType', () => {
742742
})
743743
})
744744

745+
test('TSMappedType with indexed access', () => {
746+
const { props } = resolve(
747+
`
748+
type Prettify<T> = { [K in keyof T]: T[K] } & {}
749+
type Side = 'top' | 'right' | 'bottom' | 'left'
750+
type AlignedPlacement = \`\${Side}-\${Alignment}\`
751+
type Alignment = 'start' | 'end'
752+
type Placement = Prettify<Side | AlignedPlacement>
753+
defineProps<{placement?: Placement}>()
754+
`,
755+
)
756+
expect(props).toStrictEqual({
757+
placement: ['String', 'Object'],
758+
})
759+
})
760+
745761
describe('type alias declaration', () => {
746762
// #13240
747763
test('function type', () => {

packages/compiler-sfc/src/script/resolveType.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1788,6 +1788,47 @@ export function inferRuntimeType(
17881788
typeParameters,
17891789
).filter(t => t !== UNKNOWN_TYPE)
17901790
}
1791+
case 'TSMappedType': {
1792+
// only support { [K in keyof T]: T[K] }
1793+
const { typeAnnotation, typeParameter } = node
1794+
if (
1795+
typeAnnotation &&
1796+
typeAnnotation.type === 'TSIndexedAccessType' &&
1797+
typeParameter &&
1798+
typeParameter.constraint &&
1799+
typeParameters
1800+
) {
1801+
const constraint = typeParameter.constraint
1802+
if (
1803+
constraint.type === 'TSTypeOperator' &&
1804+
constraint.operator === 'keyof' &&
1805+
constraint.typeAnnotation &&
1806+
constraint.typeAnnotation.type === 'TSTypeReference' &&
1807+
constraint.typeAnnotation.typeName.type === 'Identifier'
1808+
) {
1809+
const typeName = constraint.typeAnnotation.typeName.name
1810+
const index = typeAnnotation.indexType
1811+
const obj = typeAnnotation.objectType
1812+
if (
1813+
obj &&
1814+
obj.type === 'TSTypeReference' &&
1815+
obj.typeName.type === 'Identifier' &&
1816+
obj.typeName.name === typeName &&
1817+
index &&
1818+
index.type === 'TSTypeReference' &&
1819+
index.typeName.type === 'Identifier' &&
1820+
index.typeName.name === typeParameter.name
1821+
) {
1822+
const targetType = typeParameters[typeName]
1823+
if (targetType) {
1824+
return inferRuntimeType(ctx, targetType, scope)
1825+
}
1826+
}
1827+
}
1828+
}
1829+
1830+
return [UNKNOWN_TYPE]
1831+
}
17911832

17921833
case 'TSEnumDeclaration':
17931834
return inferEnumType(node)

0 commit comments

Comments
 (0)