Skip to content

Commit 4eb46e4

Browse files
authored
fix(compile-sfc): handle mapped types work with omit and pick (#12648)
close #12647
1 parent 10ebcef commit 4eb46e4

File tree

2 files changed

+41
-5
lines changed

2 files changed

+41
-5
lines changed

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,23 @@ describe('resolveType', () => {
278278
})
279279
})
280280

281+
test('utility type: mapped type with Omit and Pick', () => {
282+
expect(
283+
resolve(`
284+
type Optional<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>
285+
interface Test {
286+
foo: string;
287+
bar?: string;
288+
}
289+
type OptionalTest = Optional<Test, 'foo'>
290+
defineProps<OptionalTest>()
291+
`).props,
292+
).toStrictEqual({
293+
foo: ['String'],
294+
bar: ['String'],
295+
})
296+
})
297+
281298
test('utility type: ReadonlyArray', () => {
282299
expect(
283300
resolve(`

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

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -546,26 +546,43 @@ function resolveStringType(
546546
ctx: TypeResolveContext,
547547
node: Node,
548548
scope: TypeScope,
549+
typeParameters?: Record<string, Node>,
549550
): string[] {
550551
switch (node.type) {
551552
case 'StringLiteral':
552553
return [node.value]
553554
case 'TSLiteralType':
554-
return resolveStringType(ctx, node.literal, scope)
555+
return resolveStringType(ctx, node.literal, scope, typeParameters)
555556
case 'TSUnionType':
556-
return node.types.map(t => resolveStringType(ctx, t, scope)).flat()
557+
return node.types
558+
.map(t => resolveStringType(ctx, t, scope, typeParameters))
559+
.flat()
557560
case 'TemplateLiteral': {
558561
return resolveTemplateKeys(ctx, node, scope)
559562
}
560563
case 'TSTypeReference': {
561564
const resolved = resolveTypeReference(ctx, node, scope)
562565
if (resolved) {
563-
return resolveStringType(ctx, resolved, scope)
566+
return resolveStringType(ctx, resolved, scope, typeParameters)
564567
}
565568
if (node.typeName.type === 'Identifier') {
569+
const name = node.typeName.name
570+
if (typeParameters && typeParameters[name]) {
571+
return resolveStringType(
572+
ctx,
573+
typeParameters[name],
574+
scope,
575+
typeParameters,
576+
)
577+
}
566578
const getParam = (index = 0) =>
567-
resolveStringType(ctx, node.typeParameters!.params[index], scope)
568-
switch (node.typeName.name) {
579+
resolveStringType(
580+
ctx,
581+
node.typeParameters!.params[index],
582+
scope,
583+
typeParameters,
584+
)
585+
switch (name) {
569586
case 'Extract':
570587
return getParam(1)
571588
case 'Exclude': {
@@ -671,6 +688,7 @@ function resolveBuiltin(
671688
ctx,
672689
node.typeParameters!.params[1],
673690
scope,
691+
typeParameters,
674692
)
675693
const res: ResolvedElements = { props: {}, calls: t.calls }
676694
for (const key of picked) {
@@ -683,6 +701,7 @@ function resolveBuiltin(
683701
ctx,
684702
node.typeParameters!.params[1],
685703
scope,
704+
typeParameters,
686705
)
687706
const res: ResolvedElements = { props: {}, calls: t.calls }
688707
for (const key in t.props) {

0 commit comments

Comments
 (0)