Skip to content

Commit

Permalink
fix(compiler-sfc): support as keyword with template literal types
Browse files Browse the repository at this point in the history
  • Loading branch information
0xEFEF committed Jun 10, 2024
1 parent 2c78f89 commit d177997
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 2 deletions.
31 changes: 31 additions & 0 deletions packages/compiler-sfc/__tests__/compileScript/resolveType.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
13 changes: 11 additions & 2 deletions packages/compiler-sfc/src/script/resolveType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -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(
{
Expand Down

0 comments on commit d177997

Please sign in to comment.