})
})
+ // #11129
+ test('keyof: intersection type', () => {
+ const { props } = resolve(`
+ type A = { name: string }
+ type B = A & { [key: number]: string }
+ defineProps<{
+ foo: keyof B
+ }>()`)
+ expect(props).toStrictEqual({
+ foo: ['String', 'Number'],
+ })
+ })
+
+ test('keyof: union type', () => {
+ const { props } = resolve(`
+ type A = { name: string }
+ type B = A | { [key: number]: string }
+ defineProps<{
+ foo: keyof B
+ }>()`)
+ expect(props).toStrictEqual({
+ foo: ['String', 'Number'],
+ })
+ })
+
test('keyof: utility type', () => {
const { props } = resolve(
`
return inferRuntimeType(ctx, node.typeAnnotation, scope)
case 'TSUnionType':
- return flattenTypes(ctx, node.types, scope)
+ return flattenTypes(ctx, node.types, scope, isKeyOf)
case 'TSIntersectionType': {
- return flattenTypes(ctx, node.types, scope).filter(
+ return flattenTypes(ctx, node.types, scope, isKeyOf).filter(
t => t !== UNKNOWN_TYPE,
)
}
ctx: TypeResolveContext,
types: TSType[],
scope: TypeScope,
+ isKeyOf: boolean = false,
): string[] {
if (types.length === 1) {
- return inferRuntimeType(ctx, types[0], scope)
+ return inferRuntimeType(ctx, types[0], scope, isKeyOf)
}
return [
...new Set(
([] as string[]).concat(
- ...types.map(t => inferRuntimeType(ctx, t, scope)),
+ ...types.map(t => inferRuntimeType(ctx, t, scope, isKeyOf)),
),
),
]