mirror of https://github.com/vuejs/core.git
parent
83661264a4
commit
10d34a5624
|
@ -447,6 +447,42 @@ describe('resolveType', () => {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('keyof', () => {
|
||||||
|
const files = {
|
||||||
|
'/foo.ts': `export type IMP = { ${1}: 1 };`,
|
||||||
|
}
|
||||||
|
|
||||||
|
const { props } = resolve(
|
||||||
|
`
|
||||||
|
import { IMP } from './foo'
|
||||||
|
interface Foo { foo: 1, ${1}: 1 }
|
||||||
|
type Bar = { bar: 1 }
|
||||||
|
declare const obj: Bar
|
||||||
|
declare const set: Set<any>
|
||||||
|
declare const arr: Array<any>
|
||||||
|
|
||||||
|
defineProps<{
|
||||||
|
imp: keyof IMP,
|
||||||
|
foo: keyof Foo,
|
||||||
|
bar: keyof Bar,
|
||||||
|
obj: keyof typeof obj,
|
||||||
|
set: keyof typeof set,
|
||||||
|
arr: keyof typeof arr
|
||||||
|
}>()
|
||||||
|
`,
|
||||||
|
files,
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(props).toStrictEqual({
|
||||||
|
imp: ['Number'],
|
||||||
|
foo: ['String', 'Number'],
|
||||||
|
bar: ['String'],
|
||||||
|
obj: ['String'],
|
||||||
|
set: ['String'],
|
||||||
|
arr: ['String', 'Number'],
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
test('ExtractPropTypes (element-plus)', () => {
|
test('ExtractPropTypes (element-plus)', () => {
|
||||||
const { props, raw } = resolve(
|
const { props, raw } = resolve(
|
||||||
`
|
`
|
||||||
|
|
|
@ -1448,6 +1448,7 @@ export function inferRuntimeType(
|
||||||
ctx: TypeResolveContext,
|
ctx: TypeResolveContext,
|
||||||
node: Node & MaybeWithScope,
|
node: Node & MaybeWithScope,
|
||||||
scope = node._ownerScope || ctxToScope(ctx),
|
scope = node._ownerScope || ctxToScope(ctx),
|
||||||
|
isKeyOf = false,
|
||||||
): string[] {
|
): string[] {
|
||||||
try {
|
try {
|
||||||
switch (node.type) {
|
switch (node.type) {
|
||||||
|
@ -1467,8 +1468,18 @@ export function inferRuntimeType(
|
||||||
const types = new Set<string>()
|
const types = new Set<string>()
|
||||||
const members =
|
const members =
|
||||||
node.type === 'TSTypeLiteral' ? node.members : node.body.body
|
node.type === 'TSTypeLiteral' ? node.members : node.body.body
|
||||||
|
|
||||||
for (const m of members) {
|
for (const m of members) {
|
||||||
if (
|
if (isKeyOf) {
|
||||||
|
if (
|
||||||
|
m.type === 'TSPropertySignature' &&
|
||||||
|
m.key.type === 'NumericLiteral'
|
||||||
|
) {
|
||||||
|
types.add('Number')
|
||||||
|
} else {
|
||||||
|
types.add('String')
|
||||||
|
}
|
||||||
|
} else if (
|
||||||
m.type === 'TSCallSignatureDeclaration' ||
|
m.type === 'TSCallSignatureDeclaration' ||
|
||||||
m.type === 'TSConstructSignatureDeclaration'
|
m.type === 'TSConstructSignatureDeclaration'
|
||||||
) {
|
) {
|
||||||
|
@ -1477,6 +1488,7 @@ export function inferRuntimeType(
|
||||||
types.add('Object')
|
types.add('Object')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return types.size ? Array.from(types) : ['Object']
|
return types.size ? Array.from(types) : ['Object']
|
||||||
}
|
}
|
||||||
case 'TSPropertySignature':
|
case 'TSPropertySignature':
|
||||||
|
@ -1512,9 +1524,22 @@ export function inferRuntimeType(
|
||||||
case 'TSTypeReference': {
|
case 'TSTypeReference': {
|
||||||
const resolved = resolveTypeReference(ctx, node, scope)
|
const resolved = resolveTypeReference(ctx, node, scope)
|
||||||
if (resolved) {
|
if (resolved) {
|
||||||
return inferRuntimeType(ctx, resolved, resolved._ownerScope)
|
return inferRuntimeType(ctx, resolved, resolved._ownerScope, isKeyOf)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node.typeName.type === 'Identifier') {
|
if (node.typeName.type === 'Identifier') {
|
||||||
|
if (isKeyOf) {
|
||||||
|
switch (node.typeName.name) {
|
||||||
|
case 'String':
|
||||||
|
case 'Array':
|
||||||
|
case 'ArrayLike':
|
||||||
|
case 'ReadonlyArray':
|
||||||
|
return ['String', 'Number']
|
||||||
|
default:
|
||||||
|
return ['String']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch (node.typeName.name) {
|
switch (node.typeName.name) {
|
||||||
case 'Array':
|
case 'Array':
|
||||||
case 'Function':
|
case 'Function':
|
||||||
|
@ -1634,7 +1659,7 @@ export function inferRuntimeType(
|
||||||
// typeof only support identifier in local scope
|
// typeof only support identifier in local scope
|
||||||
const matched = scope.declares[id.name]
|
const matched = scope.declares[id.name]
|
||||||
if (matched) {
|
if (matched) {
|
||||||
return inferRuntimeType(ctx, matched, matched._ownerScope)
|
return inferRuntimeType(ctx, matched, matched._ownerScope, isKeyOf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
|
@ -1642,7 +1667,12 @@ export function inferRuntimeType(
|
||||||
|
|
||||||
// e.g. readonly
|
// e.g. readonly
|
||||||
case 'TSTypeOperator': {
|
case 'TSTypeOperator': {
|
||||||
return inferRuntimeType(ctx, node.typeAnnotation, scope)
|
return inferRuntimeType(
|
||||||
|
ctx,
|
||||||
|
node.typeAnnotation,
|
||||||
|
scope,
|
||||||
|
node.operator === 'keyof',
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
Loading…
Reference in New Issue