@@ -450,7 +450,7 @@ export class TypeTable {
450
450
this . isInShallowTypeContext ? TypeExtractionState . PendingShallow : TypeExtractionState . PendingFull ) ;
451
451
// If the type is the self-type for a named type (not a generic instantiation of it),
452
452
// 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 ) ) {
454
454
this . selfTypes . symbols . push ( this . getSymbolId ( type . aliasSymbol || type . symbol ) ) ;
455
455
this . selfTypes . selfTypes . push ( id ) ;
456
456
}
@@ -1357,3 +1357,30 @@ function isFunctionTypeOrTypeAlias(declaration: ts.Declaration | undefined) {
1357
1357
if ( declaration == null ) return false ;
1358
1358
return declaration . kind === ts . SyntaxKind . FunctionType || declaration . kind === ts . SyntaxKind . TypeAliasDeclaration ;
1359
1359
}
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