Skip to content
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

Union type inference lost on assignment #23523

Closed
amacleay opened this issue Apr 18, 2018 · 2 comments
Closed

Union type inference lost on assignment #23523

amacleay opened this issue Apr 18, 2018 · 2 comments
Labels
Design Limitation Constraints of the existing architecture prevent this from being fixed

Comments

@amacleay
Copy link

TypeScript Version: 2.9.0-dev.20180418

Search Terms: union type strictnullchecks inference

Code

interface Person {
  name: string;                           
  address: {                              
    street?: string;
    city: string;                         
  };                                      
}                                         
                                          
declare function getPerson(): Person;     
                                          
function getMinimalAddress(): string {    
  const person = getPerson();             
  if (person.address.street) {            
    const address = person.address;
    return address.street; // ERROR on this line
  } else {                                
    return person.address.city;           
  }                                       
}

Expected behavior:
Passes type checker. Since person.address.street is either null or a string, and since there is a check on line 13 for person.address.street being truthy, we know that address.street is a string.

You can get the type checker to pass by omitting the reassignment:

--- broken.ts   2018-04-18 16:01:26.188724623 -0400                                 
+++ works.ts    2018-04-18 16:01:26.192724616 -0400                                 
@@ -11,8 +11,7 @@                         
 function getMinimalAddress(): string {   
   const person = getPerson();            
   if (person.address.street) {           
-    const address = person.address;      
-    return address.street;               
+    return person.address.street;        
   } else {                               
     return person.address.city;          
   }

Actual behavior:

$ tsc --strictnullChecks broken.ts 
broken.ts(15,5): error TS2322: Type 'string | undefined' is not assignable to type 'string'.
  Type 'undefined' is not assignable to type 'string'.

Playground Link: playground link

Related Issues:
#22635
#16069

@RyanCavanaugh RyanCavanaugh added the Design Limitation Constraints of the existing architecture prevent this from being fixed label Apr 18, 2018
@RyanCavanaugh
Copy link
Member

We track these guards based on the expressions used to test them; unfortunately the type checker is not implemented in a way that it actually understands that address and person.address are references to the same object. There's not a lot we can do here short of a wholesale rewrite of the type guard logic, which isn't really in the cards to fix something like this.

@typescript-bot
Copy link
Collaborator

Automatically closing this issue for housekeeping purposes. The issue labels indicate that it is unactionable at the moment or has already been addressed.

@microsoft microsoft locked and limited conversation to collaborators Jul 31, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Design Limitation Constraints of the existing architecture prevent this from being fixed
Projects
None yet
Development

No branches or pull requests

3 participants