Skip to content

Commit b8f8f8b

Browse files
committed
fix(compile-sfc): handle mapped types work with omit and pick
1 parent e8e8422 commit b8f8f8b

File tree

2 files changed

+35
-4
lines changed

2 files changed

+35
-4
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: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -546,26 +546,38 @@ 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) =>
567579
resolveStringType(ctx, node.typeParameters!.params[index], scope)
568-
switch (node.typeName.name) {
580+
switch (name) {
569581
case 'Extract':
570582
return getParam(1)
571583
case 'Exclude': {
@@ -671,6 +683,7 @@ function resolveBuiltin(
671683
ctx,
672684
node.typeParameters!.params[1],
673685
scope,
686+
typeParameters,
674687
)
675688
const res: ResolvedElements = { props: {}, calls: t.calls }
676689
for (const key of picked) {
@@ -683,6 +696,7 @@ function resolveBuiltin(
683696
ctx,
684697
node.typeParameters!.params[1],
685698
scope,
699+
typeParameters,
686700
)
687701
const res: ResolvedElements = { props: {}, calls: t.calls }
688702
for (const key in t.props) {

0 commit comments

Comments
 (0)