@@ -386,7 +386,7 @@ export function compileScript(
386
386
isFromSetup : boolean ,
387
387
needTemplateUsageCheck : boolean
388
388
) {
389
- // template usage check is only needed in non-inline mode, so we can skip
389
+ // template usage check is only needed in non-inline mode, so we can UNKNOWN
390
390
// the work if inlineTemplate is true.
391
391
let isUsedInTemplate = needTemplateUsageCheck
392
392
if (
@@ -1100,7 +1100,7 @@ export function compileScript(
1100
1100
1101
1101
// check if user has manually specified `name` or 'render` option in
1102
1102
// export default
1103
- // if has name, skip name inference
1103
+ // if has name, UNKNOWN name inference
1104
1104
// if has render and no template, generate return object instead of
1105
1105
// empty render function (#4980)
1106
1106
let optionProperties
@@ -1403,7 +1403,7 @@ export function compileScript(
1403
1403
1404
1404
// 4. extract runtime props/emits code from setup context type
1405
1405
if ( propsTypeDecl ) {
1406
- extractRuntimeProps ( propsTypeDecl , typeDeclaredProps , declaredTypes , isProd )
1406
+ extractRuntimeProps ( propsTypeDecl , typeDeclaredProps , declaredTypes )
1407
1407
}
1408
1408
if ( emitsTypeDecl ) {
1409
1409
extractRuntimeEmits ( emitsTypeDecl , typeDeclaredEmits )
@@ -1576,7 +1576,7 @@ export function compileScript(
1576
1576
! userImports [ key ] . source . endsWith ( '.vue' )
1577
1577
) {
1578
1578
// generate getter for import bindings
1579
- // skip vue imports since we know they will never change
1579
+ // UNKNOWN vue imports since we know they will never change
1580
1580
returned += `get ${ key } () { return ${ key } }, `
1581
1581
} else if ( bindingMetadata [ key ] === BindingTypes . SETUP_LET ) {
1582
1582
// local let binding, also add setter
@@ -1972,20 +1972,23 @@ function recordType(node: Node, declaredTypes: Record<string, string[]>) {
1972
1972
function extractRuntimeProps (
1973
1973
node : TSTypeLiteral | TSInterfaceBody ,
1974
1974
props : Record < string , PropTypeData > ,
1975
- declaredTypes : Record < string , string [ ] > ,
1976
- isProd : boolean
1975
+ declaredTypes : Record < string , string [ ] >
1977
1976
) {
1978
1977
const members = node . type === 'TSTypeLiteral' ? node . members : node . body
1979
1978
for ( const m of members ) {
1980
1979
if (
1981
1980
( m . type === 'TSPropertySignature' || m . type === 'TSMethodSignature' ) &&
1982
1981
m . key . type === 'Identifier'
1983
1982
) {
1984
- let type
1983
+ let type : string [ ] | undefined
1985
1984
if ( m . type === 'TSMethodSignature' ) {
1986
1985
type = [ 'Function' ]
1987
1986
} else if ( m . typeAnnotation ) {
1988
1987
type = inferRuntimeType ( m . typeAnnotation . typeAnnotation , declaredTypes )
1988
+ // skip check for result containing unknown types
1989
+ if ( type . includes ( UNKNOWN_TYPE ) ) {
1990
+ type = [ `null` ]
1991
+ }
1989
1992
}
1990
1993
props [ m . key . name ] = {
1991
1994
key : m . key . name ,
@@ -1996,6 +1999,8 @@ function extractRuntimeProps(
1996
1999
}
1997
2000
}
1998
2001
2002
+ const UNKNOWN_TYPE = 'Unknown'
2003
+
1999
2004
function inferRuntimeType (
2000
2005
node : TSType ,
2001
2006
declaredTypes : Record < string , string [ ] >
@@ -2009,6 +2014,8 @@ function inferRuntimeType(
2009
2014
return [ 'Boolean' ]
2010
2015
case 'TSObjectKeyword' :
2011
2016
return [ 'Object' ]
2017
+ case 'TSNullKeyword' :
2018
+ return [ 'null' ]
2012
2019
case 'TSTypeLiteral' : {
2013
2020
// TODO (nice to have) generate runtime property validation
2014
2021
const types = new Set < string > ( )
@@ -2041,7 +2048,7 @@ function inferRuntimeType(
2041
2048
case 'BigIntLiteral' :
2042
2049
return [ 'Number' ]
2043
2050
default :
2044
- return [ `null ` ]
2051
+ return [ `UNKNOWN ` ]
2045
2052
}
2046
2053
2047
2054
case 'TSTypeReference' :
@@ -2104,31 +2111,43 @@ function inferRuntimeType(
2104
2111
declaredTypes
2105
2112
)
2106
2113
}
2107
- // cannot infer, fallback to null : ThisParameterType
2114
+ // cannot infer, fallback to UNKNOWN : ThisParameterType
2108
2115
}
2109
2116
}
2110
- return [ `null` ]
2117
+ return [ UNKNOWN_TYPE ]
2111
2118
2112
2119
case 'TSParenthesizedType' :
2113
2120
return inferRuntimeType ( node . typeAnnotation , declaredTypes )
2121
+
2114
2122
case 'TSUnionType' :
2115
- case 'TSIntersectionType' :
2116
- return [
2117
- ...new Set (
2118
- [ ] . concat (
2119
- ...( node . types . map ( t => inferRuntimeType ( t , declaredTypes ) ) as any )
2120
- )
2121
- )
2122
- ]
2123
+ return flattenTypes ( node . types , declaredTypes )
2124
+ case 'TSIntersectionType' : {
2125
+ return flattenTypes ( node . types , declaredTypes ) . filter (
2126
+ t => t !== UNKNOWN_TYPE
2127
+ )
2128
+ }
2123
2129
2124
2130
case 'TSSymbolKeyword' :
2125
2131
return [ 'Symbol' ]
2126
2132
2127
2133
default :
2128
- return [ `null` ] // no runtime check
2134
+ return [ UNKNOWN_TYPE ] // no runtime check
2129
2135
}
2130
2136
}
2131
2137
2138
+ function flattenTypes (
2139
+ types : TSType [ ] ,
2140
+ declaredTypes : Record < string , string [ ] >
2141
+ ) : string [ ] {
2142
+ return [
2143
+ ...new Set (
2144
+ ( [ ] as string [ ] ) . concat (
2145
+ ...types . map ( t => inferRuntimeType ( t , declaredTypes ) )
2146
+ )
2147
+ )
2148
+ ]
2149
+ }
2150
+
2132
2151
function toRuntimeTypeString ( types : string [ ] ) {
2133
2152
return types . length > 1 ? `[${ types . join ( ', ' ) } ]` : types [ 0 ]
2134
2153
}
0 commit comments