@@ -450,7 +450,7 @@ export class TypeTable {
450450 this . isInShallowTypeContext ? TypeExtractionState . PendingShallow : TypeExtractionState . PendingFull ) ;
451451 // If the type is the self-type for a named type (not a generic instantiation of it),
452452 // emit the self-type binding for that type.
453- if ( content . startsWith ( "reference;" ) && ! ( isTypeReference ( type ) && type . target !== type ) ) {
453+ if ( content . startsWith ( "reference;" ) && isTypeSelfReference ( type ) ) {
454454 this . selfTypes . symbols . push ( this . getSymbolId ( type . aliasSymbol || type . symbol ) ) ;
455455 this . selfTypes . selfTypes . push ( id ) ;
456456 }
@@ -1357,3 +1357,30 @@ function isFunctionTypeOrTypeAlias(declaration: ts.Declaration | undefined) {
13571357 if ( declaration == null ) return false ;
13581358 return declaration . kind === ts . SyntaxKind . FunctionType || declaration . kind === ts . SyntaxKind . TypeAliasDeclaration ;
13591359}
1360+
1361+ /**
1362+ * Given a `type` whose type-string is known to be a `reference`, returns true if this is the self-type for the referenced type.
1363+ *
1364+ * For example, for `type Foo<R> = ...` this returns true if `type` is `Foo<R>`.
1365+ */
1366+ function isTypeSelfReference ( type : ts . Type ) {
1367+ if ( type . aliasSymbol != null ) {
1368+ const { aliasTypeArguments } = type ;
1369+ if ( aliasTypeArguments == null ) return true ;
1370+ let declaration = type . aliasSymbol . declarations ?. [ 0 ] ;
1371+ if ( declaration == null || declaration . kind !== ts . SyntaxKind . TypeAliasDeclaration ) return false ;
1372+ let alias = declaration as ts . TypeAliasDeclaration ;
1373+ for ( let i = 0 ; i < aliasTypeArguments . length ; ++ i ) {
1374+ if ( aliasTypeArguments [ i ] . symbol ?. declarations ?. [ 0 ] !== alias . typeParameters [ i ] ) {
1375+ return false ;
1376+ }
1377+ }
1378+ return true ;
1379+ } else if ( isTypeReference ( type ) ) {
1380+ return type . target === type ;
1381+ } else {
1382+ // Return true because we know we have mapped this type to kind `reference`, and in the cases
1383+ // not covered above (i.e. generic types) it is always a self-reference.
1384+ return true ;
1385+ }
1386+ }
0 commit comments