]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(compiler-sfc): enhance inferRuntimeType to support TSMappedType with indexed...
authoredison <daiwei521@126.com>
Wed, 24 Sep 2025 09:29:38 +0000 (17:29 +0800)
committerGitHub <noreply@github.com>
Wed, 24 Sep 2025 09:29:38 +0000 (17:29 +0800)
close #13847

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

index 0f46d608510d9c6226fc735bacecd54ea0169069..eff2f01b9810843f1267d0cb13017f3447816940 100644 (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', () => {
index f6763b7645df0c5cceeb889268c029c8b1e065b4..54b93b3fe7a4f222fcc41d31de6673a44784510b 100644 (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)