-
Notifications
You must be signed in to change notification settings - Fork 12.8k
strictNullChecks mode - variable initial value is ignored in the control flow #10640
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
Comments
Embrace for |
I don't know if I've managed to explain the problem clearly. I'll elaborate :) The first code snippet doesn't work and that's the bug I am writing about. The code fails on the last line |
@alitaheri This snippet might help illustrate the problem. var a: string | null = 'str'
a.split('123') // no error
a = null
a.split('123') // error |
@aliai @HerringtonDarkholme I did get the problem. It's just that I thought maybe the cast to IFoo erases the information about Interestingly, this code doesn't work either: interface IFoo {
foo?: string;
};
let a: IFoo;
a = { foo: '' };
a.foo.split(''); // <-- Error: a.foo is possibly undefined! This sure does look like a bug to me 😅 |
Naturally this works fine (inferred type of
The reason for adding the explicit type annotation is because you are planning to assign to If you don't want the help, don't ask for it! :) (just remove the type annotation from |
@danielearwicker yes for the example I provided it may look silly to annotate the type :) But, this is just a simplified example to show the bug, not the necessity. The use case of this can vary of course: interface IUser {
name: string;
permissions?: {
adminRights?: {
moreInDepthFileld: any;
thatIWouldLikeToHaveIntellisenseFor: any;
};
canPublishPost: boolean;
canLeaveComments: boolean;
};
otherThingsIMightWantForMyObject?: ISomething;
};
var user: IUser = { name: 'foo', permissions: {} };
user.permissions.canPublishPost = ...; // <-- Error This is not the code I encountered this problem with since it is out of topic here. But it is a close example to the real case. The point being, the compiler doesn't take the initialization phase of the variable into account to not infer |
We only narrow unions. the type of var a: IFoo = {};
a.foo = "";
`` |
There are some technical challenges here that would make this rather expensive in our current design. We'll think about it more and see if there's something that can be done, but there isn't an obvious solution at this time. |
Uh oh!
There was an error while loading. Please reload this page.
TypeScript Version: nightly (2.0.2)
In
strictNullChecks
mode only:Code
Expected behavior:
This is a valid piece of code.
a.foo
is defined, therefore,a.foo.split
is a valid expression.Actual behavior:
a.foo
is concluded as typestring | defined
, even though it is defined in the initiation phasevar a:IFoo = { foo: '' }
. tslint/typescript complains that foo is possibly undefined and therefore, cannot access to split method.the following code runs without problem simply because
foo
is assigned aftera
declaration:The text was updated successfully, but these errors were encountered: