Skip to content

Commit 2594b1d

Browse files
authoredJun 10, 2024··
fix(compiler-sfc): support as keyword with template literal types (#11100)
close #10962
1 parent 953e096 commit 2594b1d

File tree

2 files changed

+42
-2
lines changed

2 files changed

+42
-2
lines changed
 

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

+31
Original file line numberDiff line numberDiff line change
@@ -1198,6 +1198,37 @@ describe('resolveType', () => {
11981198
})
11991199
})
12001200
})
1201+
1202+
describe('template literals', () => {
1203+
test('mapped types with string type', () => {
1204+
expect(
1205+
resolve(`
1206+
type X = 'a' | 'b'
1207+
defineProps<{[K in X as \`\${K}_foo\`]: string}>()
1208+
`).props,
1209+
).toStrictEqual({
1210+
a_foo: ['String'],
1211+
b_foo: ['String'],
1212+
})
1213+
})
1214+
1215+
// #10962
1216+
test('mapped types with generic parameters', () => {
1217+
const { props } = resolve(`
1218+
type Breakpoints = 'sm' | 'md' | 'lg'
1219+
type BreakpointFactory<T extends string, V> = {
1220+
[K in Breakpoints as \`\${T}\${Capitalize<K>}\`]: V
1221+
}
1222+
type ColsBreakpoints = BreakpointFactory<'cols', number>
1223+
defineProps<ColsBreakpoints>()
1224+
`)
1225+
expect(props).toStrictEqual({
1226+
colsSm: ['Number'],
1227+
colsMd: ['Number'],
1228+
colsLg: ['Number'],
1229+
})
1230+
})
1231+
})
12011232
})
12021233

12031234
function resolve(

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

+11-2
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ function innerResolveTypeElements(
188188
node.type,
189189
)
190190
case 'TSMappedType':
191-
return resolveMappedType(ctx, node, scope)
191+
return resolveMappedType(ctx, node, scope, typeParameters)
192192
case 'TSIndexedAccessType': {
193193
const types = resolveIndexType(ctx, node, scope)
194194
return mergeElements(
@@ -450,9 +450,18 @@ function resolveMappedType(
450450
ctx: TypeResolveContext,
451451
node: TSMappedType,
452452
scope: TypeScope,
453+
typeParameters?: Record<string, Node>,
453454
): ResolvedElements {
454455
const res: ResolvedElements = { props: {} }
455-
const keys = resolveStringType(ctx, node.typeParameter.constraint!, scope)
456+
let keys: string[]
457+
if (node.nameType) {
458+
const { name, constraint } = node.typeParameter
459+
scope = createChildScope(scope)
460+
Object.assign(scope.types, { ...typeParameters, [name]: constraint })
461+
keys = resolveStringType(ctx, node.nameType, scope)
462+
} else {
463+
keys = resolveStringType(ctx, node.typeParameter.constraint!, scope)
464+
}
456465
for (const key of keys) {
457466
res.props[key] = createProperty(
458467
{

0 commit comments

Comments
 (0)
Please sign in to comment.