fix(compiler-sfc): support as keyword with template literal types (#11100)

close #10962
This commit is contained in:
Zhaolin Liang 2024-06-10 15:19:39 +08:00 committed by GitHub
parent 953e09670a
commit 2594b1df57
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 42 additions and 2 deletions

View File

@ -1198,6 +1198,37 @@ describe('resolveType', () => {
})
})
})
describe('template literals', () => {
test('mapped types with string type', () => {
expect(
resolve(`
type X = 'a' | 'b'
defineProps<{[K in X as \`\${K}_foo\`]: string}>()
`).props,
).toStrictEqual({
a_foo: ['String'],
b_foo: ['String'],
})
})
// #10962
test('mapped types with generic parameters', () => {
const { props } = resolve(`
type Breakpoints = 'sm' | 'md' | 'lg'
type BreakpointFactory<T extends string, V> = {
[K in Breakpoints as \`\${T}\${Capitalize<K>}\`]: V
}
type ColsBreakpoints = BreakpointFactory<'cols', number>
defineProps<ColsBreakpoints>()
`)
expect(props).toStrictEqual({
colsSm: ['Number'],
colsMd: ['Number'],
colsLg: ['Number'],
})
})
})
})
function resolve(

View File

@ -188,7 +188,7 @@ function innerResolveTypeElements(
node.type,
)
case 'TSMappedType':
return resolveMappedType(ctx, node, scope)
return resolveMappedType(ctx, node, scope, typeParameters)
case 'TSIndexedAccessType': {
const types = resolveIndexType(ctx, node, scope)
return mergeElements(
@ -450,9 +450,18 @@ function resolveMappedType(
ctx: TypeResolveContext,
node: TSMappedType,
scope: TypeScope,
typeParameters?: Record<string, Node>,
): ResolvedElements {
const res: ResolvedElements = { props: {} }
const keys = resolveStringType(ctx, node.typeParameter.constraint!, scope)
let keys: string[]
if (node.nameType) {
const { name, constraint } = node.typeParameter
scope = createChildScope(scope)
Object.assign(scope.types, { ...typeParameters, [name]: constraint })
keys = resolveStringType(ctx, node.nameType, scope)
} else {
keys = resolveStringType(ctx, node.typeParameter.constraint!, scope)
}
for (const key of keys) {
res.props[key] = createProperty(
{