From: edison Date: Thu, 5 Jun 2025 02:01:22 +0000 (+0800) Subject: fix(compile-sfc): handle mapped types work with omit and pick (#12648) X-Git-Tag: v3.5.17~24 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4eb46e443f1878199755cb73d481d318a9714392;p=thirdparty%2Fvuejs%2Fcore.git fix(compile-sfc): handle mapped types work with omit and pick (#12648) close #12647 --- diff --git a/packages/compiler-sfc/__tests__/compileScript/resolveType.spec.ts b/packages/compiler-sfc/__tests__/compileScript/resolveType.spec.ts index 4ced9b8879..68fc5cc315 100644 --- a/packages/compiler-sfc/__tests__/compileScript/resolveType.spec.ts +++ b/packages/compiler-sfc/__tests__/compileScript/resolveType.spec.ts @@ -278,6 +278,23 @@ describe('resolveType', () => { }) }) + test('utility type: mapped type with Omit and Pick', () => { + expect( + resolve(` + type Optional = Omit & Partial> + interface Test { + foo: string; + bar?: string; + } + type OptionalTest = Optional + defineProps() + `).props, + ).toStrictEqual({ + foo: ['String'], + bar: ['String'], + }) + }) + test('utility type: ReadonlyArray', () => { expect( resolve(` diff --git a/packages/compiler-sfc/src/script/resolveType.ts b/packages/compiler-sfc/src/script/resolveType.ts index 3507a783c7..85832dfc39 100644 --- a/packages/compiler-sfc/src/script/resolveType.ts +++ b/packages/compiler-sfc/src/script/resolveType.ts @@ -546,26 +546,43 @@ function resolveStringType( ctx: TypeResolveContext, node: Node, scope: TypeScope, + typeParameters?: Record, ): string[] { switch (node.type) { case 'StringLiteral': return [node.value] case 'TSLiteralType': - return resolveStringType(ctx, node.literal, scope) + return resolveStringType(ctx, node.literal, scope, typeParameters) case 'TSUnionType': - return node.types.map(t => resolveStringType(ctx, t, scope)).flat() + return node.types + .map(t => resolveStringType(ctx, t, scope, typeParameters)) + .flat() case 'TemplateLiteral': { return resolveTemplateKeys(ctx, node, scope) } case 'TSTypeReference': { const resolved = resolveTypeReference(ctx, node, scope) if (resolved) { - return resolveStringType(ctx, resolved, scope) + return resolveStringType(ctx, resolved, scope, typeParameters) } if (node.typeName.type === 'Identifier') { + const name = node.typeName.name + if (typeParameters && typeParameters[name]) { + return resolveStringType( + ctx, + typeParameters[name], + scope, + typeParameters, + ) + } const getParam = (index = 0) => - resolveStringType(ctx, node.typeParameters!.params[index], scope) - switch (node.typeName.name) { + resolveStringType( + ctx, + node.typeParameters!.params[index], + scope, + typeParameters, + ) + switch (name) { case 'Extract': return getParam(1) case 'Exclude': { @@ -671,6 +688,7 @@ function resolveBuiltin( ctx, node.typeParameters!.params[1], scope, + typeParameters, ) const res: ResolvedElements = { props: {}, calls: t.calls } for (const key of picked) { @@ -683,6 +701,7 @@ function resolveBuiltin( ctx, node.typeParameters!.params[1], scope, + typeParameters, ) const res: ResolvedElements = { props: {}, calls: t.calls } for (const key in t.props) {