-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Preserve type refinements in closures created past last assignment #56908
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 4 commits
86f50c6
f698783
bdbc388
2739399
a490ef4
e2d90d9
adda3ee
9a1faff
1cccdf2
5aff92b
e0ccb0d
cd9b30a
1466ba5
28da1c5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5826,7 +5826,7 @@ export interface Symbol { | |
/** @internal */ constEnumOnlyModule: boolean | undefined; // True if module contains only const enums or other modules with only const enums | ||
/** @internal */ isReferenced?: SymbolFlags; // True if the symbol is referenced elsewhere. Keeps track of the meaning of a reference in case a symbol is both a type parameter and parameter. | ||
/** @internal */ isReplaceableByMethod?: boolean; // Can this Javascript class property be replaced by a method symbol? | ||
/** @internal */ isAssigned?: boolean; // True if the symbol is a parameter with assignments | ||
/** @internal */ lastAssignmentPos?: number; // Last node that assigns value to symbol | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider placing this next to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure. |
||
/** @internal */ assignmentDeclarationMembers?: Map<number, Declaration>; // detected late-bound assignment declarations associated with the symbol | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,10 +14,6 @@ controlFlowAliasing.ts(112,13): error TS2339: Property 'foo' does not exist on t | |
Property 'foo' does not exist on type '{ kind: "bar"; bar: number; }'. | ||
controlFlowAliasing.ts(115,13): error TS2339: Property 'bar' does not exist on type '{ kind: "foo"; foo: string; } | { kind: "bar"; bar: number; }'. | ||
Property 'bar' does not exist on type '{ kind: "foo"; foo: string; }'. | ||
controlFlowAliasing.ts(134,13): error TS2339: Property 'foo' does not exist on type '{ kind: "foo"; foo: string; } | { kind: "bar"; bar: number; }'. | ||
Property 'foo' does not exist on type '{ kind: "bar"; bar: number; }'. | ||
controlFlowAliasing.ts(137,13): error TS2339: Property 'bar' does not exist on type '{ kind: "foo"; foo: string; } | { kind: "bar"; bar: number; }'. | ||
Property 'bar' does not exist on type '{ kind: "foo"; foo: string; }'. | ||
controlFlowAliasing.ts(154,19): error TS2339: Property 'foo' does not exist on type '{ kind: "foo"; foo: string; } | { kind: "bar"; bar: number; }'. | ||
Property 'foo' does not exist on type '{ kind: "bar"; bar: number; }'. | ||
controlFlowAliasing.ts(157,19): error TS2339: Property 'bar' does not exist on type '{ kind: "foo"; foo: string; } | { kind: "bar"; bar: number; }'. | ||
|
@@ -28,7 +24,7 @@ controlFlowAliasing.ts(280,5): error TS2448: Block-scoped variable 'a' used befo | |
controlFlowAliasing.ts(280,5): error TS2454: Variable 'a' is used before being assigned. | ||
|
||
|
||
==== controlFlowAliasing.ts (15 errors) ==== | ||
==== controlFlowAliasing.ts (13 errors) ==== | ||
// Narrowing by aliased conditional expressions | ||
|
||
function f10(x: string | number) { | ||
|
@@ -187,15 +183,9 @@ controlFlowAliasing.ts(280,5): error TS2454: Variable 'a' is used before being a | |
const isFoo = obj.kind === 'foo'; | ||
if (isFoo) { | ||
obj.foo; // Not narrowed because obj is mutable | ||
~~~ | ||
!!! error TS2339: Property 'foo' does not exist on type '{ kind: "foo"; foo: string; } | { kind: "bar"; bar: number; }'. | ||
!!! error TS2339: Property 'foo' does not exist on type '{ kind: "bar"; bar: number; }'. | ||
} | ||
else { | ||
obj.bar; // Not narrowed because obj is mutable | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess these comments are outdated now There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, I'll fix those. |
||
~~~ | ||
!!! error TS2339: Property 'bar' does not exist on type '{ kind: "foo"; foo: string; } | { kind: "bar"; bar: number; }'. | ||
!!! error TS2339: Property 'bar' does not exist on type '{ kind: "foo"; foo: string; }'. | ||
} | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you need to ensure that if
declaringFunction
is aSourceFile
, that it's also a module? Otherwise you can't be certain that the scope isn't global.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, that's a good point. For top-level declarations, we should only preserve refinements for const variables and non-exported mutable variables declared in external modules.