diff --git a/packages/compiler-sfc/__tests__/compileScript/resolveType.spec.ts b/packages/compiler-sfc/__tests__/compileScript/resolveType.spec.ts index 816d74bc649..87890d4dfda 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 6bb647f11ff..e5c61276572 100644 --- a/packages/compiler-sfc/src/script/resolveType.ts +++ b/packages/compiler-sfc/src/script/resolveType.ts @@ -546,26 +546,38 @@ 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) { + switch (name) { case 'Extract': return getParam(1) case 'Exclude': { @@ -671,6 +683,7 @@ function resolveBuiltin( ctx, node.typeParameters!.params[1], scope, + typeParameters, ) const res: ResolvedElements = { props: {}, calls: t.calls } for (const key of picked) { @@ -683,6 +696,7 @@ function resolveBuiltin( ctx, node.typeParameters!.params[1], scope, + typeParameters, ) const res: ResolvedElements = { props: {}, calls: t.calls } for (const key in t.props) {