@@ -1448,7 +1448,10 @@ export function inferRuntimeType(
14481448 ctx : TypeResolveContext ,
14491449 node : Node & MaybeWithScope ,
14501450 scope = node . _ownerScope || ctxToScope ( ctx ) ,
1451+ options : { isKeyof ?: boolean } = { } ,
14511452) : string [ ] {
1453+ const { isKeyof } = options
1454+
14521455 try {
14531456 switch ( node . type ) {
14541457 case 'TSStringKeyword' :
@@ -1467,16 +1470,33 @@ export function inferRuntimeType(
14671470 const types = new Set < string > ( )
14681471 const members =
14691472 node . type === 'TSTypeLiteral' ? node . members : node . body . body
1473+
1474+ const handler = isKeyof
1475+ ? ( m : TSTypeElement ) => {
1476+ if (
1477+ m . type === 'TSPropertySignature' &&
1478+ m . key . type === 'NumericLiteral'
1479+ ) {
1480+ types . add ( 'Number' )
1481+ } else {
1482+ types . add ( 'String' )
1483+ }
1484+ }
1485+ : ( m : TSTypeElement ) => {
1486+ if (
1487+ m . type === 'TSCallSignatureDeclaration' ||
1488+ m . type === 'TSConstructSignatureDeclaration'
1489+ ) {
1490+ types . add ( 'Function' )
1491+ } else {
1492+ types . add ( 'Object' )
1493+ }
1494+ }
1495+
14701496 for ( const m of members ) {
1471- if (
1472- m . type === 'TSCallSignatureDeclaration' ||
1473- m . type === 'TSConstructSignatureDeclaration'
1474- ) {
1475- types . add ( 'Function' )
1476- } else {
1477- types . add ( 'Object' )
1478- }
1497+ handler ( m )
14791498 }
1499+
14801500 return types . size ? Array . from ( types ) : [ 'Object' ]
14811501 }
14821502 case 'TSPropertySignature' :
@@ -1512,8 +1532,11 @@ export function inferRuntimeType(
15121532 case 'TSTypeReference' : {
15131533 const resolved = resolveTypeReference ( ctx , node , scope )
15141534 if ( resolved ) {
1515- return inferRuntimeType ( ctx , resolved , resolved . _ownerScope )
1535+ return inferRuntimeType ( ctx , resolved , resolved . _ownerScope , options )
15161536 }
1537+
1538+ if ( isKeyof ) return [ 'String' ]
1539+
15171540 if ( node . typeName . type === 'Identifier' ) {
15181541 switch ( node . typeName . name ) {
15191542 case 'Array' :
@@ -1634,15 +1657,17 @@ export function inferRuntimeType(
16341657 // typeof only support identifier in local scope
16351658 const matched = scope . declares [ id . name ]
16361659 if ( matched ) {
1637- return inferRuntimeType ( ctx , matched , matched . _ownerScope )
1660+ return inferRuntimeType ( ctx , matched , matched . _ownerScope , options )
16381661 }
16391662 }
16401663 break
16411664 }
16421665
16431666 // e.g. readonly
16441667 case 'TSTypeOperator' : {
1645- return inferRuntimeType ( ctx , node . typeAnnotation , scope )
1668+ return inferRuntimeType ( ctx , node . typeAnnotation , scope , {
1669+ isKeyof : node . operator === 'keyof' ,
1670+ } )
16461671 }
16471672 }
16481673 } catch ( e ) {
0 commit comments