Skip to content

Commit 5511b1b

Browse files
committed
Narrow down non-const enity name expressions within element access expressions
1 parent b970fa4 commit 5511b1b

4 files changed

+76
-22
lines changed

src/compiler/checker.ts

+2-22
Original file line numberDiff line numberDiff line change
@@ -26191,28 +26191,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2619126191

2619226192
function tryGetNameFromEntityNameExpression(node: EntityNameOrEntityNameExpression) {
2619326193
const symbol = resolveEntityName(node, SymbolFlags.Value, /*ignoreErrors*/ true);
26194-
if (!symbol || !(isConstantVariable(symbol) || (symbol.flags & SymbolFlags.EnumMember))) return undefined;
26195-
26196-
const declaration = symbol.valueDeclaration;
26197-
if (declaration === undefined) return undefined;
26198-
26199-
const type = tryGetTypeFromEffectiveTypeNode(declaration);
26200-
if (type) {
26201-
const name = tryGetNameFromType(type);
26202-
if (name !== undefined) {
26203-
return name;
26204-
}
26205-
}
26206-
if (hasOnlyExpressionInitializer(declaration) && isBlockScopedNameDeclaredBeforeUse(declaration, node)) {
26207-
const initializer = getEffectiveInitializer(declaration);
26208-
if (initializer) {
26209-
return tryGetNameFromType(getTypeOfExpression(initializer));
26210-
}
26211-
if (isEnumMember(declaration)) {
26212-
return getTextOfPropertyName(declaration.name);
26213-
}
26214-
}
26215-
return undefined;
26194+
if (!symbol || symbol.valueDeclaration && !isBlockScopedNameDeclaredBeforeUse(symbol.valueDeclaration, node)) return undefined;
26195+
return tryGetNameFromType(getTypeOfExpression(node as Expression));
2621626196
}
2621726197

2621826198
function containsMatchingReference(source: Node, target: Node) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
//// [tests/cases/compiler/typeGuardNarrowsIndexedAccessOfKnownProperty13.ts] ////
2+
3+
=== typeGuardNarrowsIndexedAccessOfKnownProperty13.ts ===
4+
interface Data {
5+
>Data : Symbol(Data, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty13.ts, 0, 0))
6+
7+
a?: number;
8+
>a : Symbol(Data.a, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty13.ts, 0, 16))
9+
}
10+
11+
declare const data: Data;
12+
>data : Symbol(data, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty13.ts, 4, 13))
13+
>Data : Symbol(Data, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty13.ts, 0, 0))
14+
15+
let key = "a" as const;
16+
>key : Symbol(key, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty13.ts, 6, 3))
17+
>const : Symbol(const)
18+
19+
if (data.a !== undefined) {
20+
>data.a : Symbol(Data.a, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty13.ts, 0, 16))
21+
>data : Symbol(data, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty13.ts, 4, 13))
22+
>a : Symbol(Data.a, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty13.ts, 0, 16))
23+
>undefined : Symbol(undefined)
24+
25+
const a = data[key];
26+
>a : Symbol(a, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty13.ts, 9, 7))
27+
>data : Symbol(data, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty13.ts, 4, 13))
28+
>key : Symbol(key, Decl(typeGuardNarrowsIndexedAccessOfKnownProperty13.ts, 6, 3))
29+
}
30+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
//// [tests/cases/compiler/typeGuardNarrowsIndexedAccessOfKnownProperty13.ts] ////
2+
3+
=== typeGuardNarrowsIndexedAccessOfKnownProperty13.ts ===
4+
interface Data {
5+
a?: number;
6+
>a : number | undefined
7+
}
8+
9+
declare const data: Data;
10+
>data : Data
11+
12+
let key = "a" as const;
13+
>key : "a"
14+
>"a" as const : "a"
15+
>"a" : "a"
16+
17+
if (data.a !== undefined) {
18+
>data.a !== undefined : boolean
19+
>data.a : number | undefined
20+
>data : Data
21+
>a : number | undefined
22+
>undefined : undefined
23+
24+
const a = data[key];
25+
>a : number
26+
>data[key] : number
27+
>data : Data
28+
>key : "a"
29+
}
30+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// @strict: true
2+
// @noEmit: true
3+
4+
interface Data {
5+
a?: number;
6+
}
7+
8+
declare const data: Data;
9+
10+
let key = "a" as const;
11+
12+
if (data.a !== undefined) {
13+
const a = data[key];
14+
}

0 commit comments

Comments
 (0)