Skip to content

Commit aae3115

Browse files
authored
Call getTypeOfSymbol in getNarrowedTypeOfSymbol to avoid running into circularities when computing types (#51914)
1 parent 3c7660a commit aae3115

File tree

5 files changed

+48
-1
lines changed

5 files changed

+48
-1
lines changed

src/compiler/checker.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27083,6 +27083,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2708327083
}
2708427084

2708527085
function getNarrowedTypeOfSymbol(symbol: Symbol, location: Identifier) {
27086+
const type = getTypeOfSymbol(symbol);
2708627087
const declaration = symbol.valueDeclaration;
2708727088
if (declaration) {
2708827089
// If we have a non-rest binding element with no initializer declared as a const variable or a const-like
@@ -27163,7 +27164,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2716327164
}
2716427165
}
2716527166
}
27166-
return getTypeOfSymbol(symbol);
27167+
return type;
2716727168
}
2716827169

2716927170
function checkIdentifier(node: Identifier, checkMode: CheckMode | undefined): Type {

src/harness/fourslashImpl.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1144,6 +1144,17 @@ export class TestState {
11441144
}
11451145
}
11461146

1147+
public verifyTypeAtLocation(range: Range, expected: string): void {
1148+
const node = this.goToAndGetNode(range);
1149+
const checker = this.getChecker();
1150+
const type = checker.getTypeAtLocation(node);
1151+
1152+
const actual = checker.typeToString(type);
1153+
if (actual !== expected) {
1154+
this.raiseError(displayExpectedAndActualString(expected, actual));
1155+
}
1156+
}
1157+
11471158
public verifyBaselineFindAllReferences(...markerNames: string[]) {
11481159
ts.Debug.assert(markerNames.length > 0, "Must pass at least one marker name to `verifyBaselineFindAllReferences()`");
11491160
this.verifyBaselineFindAllReferencesWorker("", markerNames);

src/harness/fourslashInterfaceImpl.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,10 @@ export class Verify extends VerifyNegatable {
354354
this.state.verifyTypeOfSymbolAtLocation(range, symbol, expected);
355355
}
356356

357+
public typeAtLocation(range: FourSlash.Range, expected: string) {
358+
this.state.verifyTypeAtLocation(range, expected);
359+
}
360+
357361
public baselineFindAllReferences(...markerNames: string[]) {
358362
this.state.verifyBaselineFindAllReferences(...markerNames);
359363
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/// <reference path='fourslash.ts' />
2+
3+
// Issue #48313
4+
5+
// @strict: true
6+
// @target: esnext
7+
// @Filename: /file.tsx
8+
//// export function working(baseVersion?: string): number[] {
9+
//// const toRelease: number[] = [];
10+
//// const baseRelease: number[] = [];
11+
//// return baseRelease.map((_, index) => {
12+
//// const toPart = toRelease[index] ?? 0;
13+
//// [|toPart|]; // this is the "working" log
14+
//// return 0;
15+
//// });
16+
//// }
17+
////
18+
//// export function broken(baseVersion?: string): number[] {
19+
//// const toRelease: number[] = [];
20+
//// const baseRelease: number[] = [];
21+
//// return baseRelease.map((_, index) => {
22+
//// const toPart = toRelease[index] ?? 0;
23+
//// [|toPart|]; // this is the "broken" log
24+
//// return toPart + (baseVersion === undefined ? 0 : 1);
25+
//// });
26+
//// }
27+
28+
const [r_ok, r_bad] = test.ranges();
29+
verify.typeAtLocation(r_ok, "number");
30+
verify.typeAtLocation(r_bad, "number");

tests/cases/fourslash/fourslash.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,7 @@ declare namespace FourSlashInterface {
335335
baselineGetFileReferences(fileName: string): void;
336336
symbolAtLocation(startRange: Range, ...declarationRanges: Range[]): void;
337337
typeOfSymbolAtLocation(range: Range, symbol: any, expected: string): void;
338+
typeAtLocation(range: Range, expected: string): void;
338339
/** @deprecated Use baselineFindAllReferences instead */
339340
singleReferenceGroup(definition: ReferencesDefinition, ranges?: Range[] | string): void;
340341
rangesAreOccurrences(isWriteAccess?: boolean, ranges?: Range[]): void;

0 commit comments

Comments
 (0)