@@ -114,6 +114,23 @@ export class FileIndexer {
114
114
115
115
ts . forEachChild ( node , child => this . visit ( child ) )
116
116
}
117
+
118
+ // Given the type of `node`, assigns the types of its children. For example,
119
+ // when the node is a function declaration, we take the return type of the
120
+ // function and assign it to its body.
121
+ //
122
+ // The reason we do this is because the TypeScript compiler APIs don't seem to
123
+ // expose hooks to register when an object type satisfies a nominal type like
124
+ // in the example below:
125
+ //
126
+ // const x: NominalType = {property: 42}
127
+ //
128
+ // When asking for the type of the `{property: 42}` expression, we get the
129
+ // structal type `{property: number}` instead of `NominalType`. Without this
130
+ // manual tracking of types, "Go to definition" on `property` does not go
131
+ // anywhere because it's the property of a structural/anonymous type. With
132
+ // this manual tracking, we know that `property` goes to
133
+ // `NominalType.property`.
117
134
private updatedAssignedTypeMap ( node : ts . Node ) : void {
118
135
if ( ts . isVariableDeclaration ( node ) && node . type && node . initializer ) {
119
136
this . assignedType . set ( node . initializer , {
@@ -209,7 +226,6 @@ export class FileIndexer {
209
226
const returnType = this . checker . getReturnTypeOfSignature ( callSignature )
210
227
this . assignedType . set ( node . body , { ...mapped , tpe : returnType } )
211
228
}
212
- // TODO: handle the case when the assigned type of `() => T` and we assign thebody of the function to type `T`
213
229
}
214
230
}
215
231
@@ -488,6 +504,7 @@ export class FileIndexer {
488
504
}
489
505
return relationships
490
506
}
507
+
491
508
private scipSymbol ( node : ts . Node ) : ScipSymbol {
492
509
const fromCache : ScipSymbol | undefined =
493
510
this . globalSymbolTable . get ( node ) || this . localSymbolTable . get ( node )
0 commit comments