Type guard should infer the type of parent object when applied on a property
See original GitHub issueSuggestion
🔍 Search Terms
Type guard, parent object, infer, inference
✅ Viability Checklist
My suggestion meets these guidelines:
- This wouldn’t be a breaking change in existing TypeScript/JavaScript code
- This wouldn’t change the runtime behavior of existing JavaScript code
- This could be implemented without emitting different JS based on the types of the expressions
- This isn’t a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)
- This feature would agree with the rest of TypeScript’s Design Goals.
⭐ Suggestion
Typescript should be able to infer the type of an object, if a type guard was checked on a property of the said object. Currently, Typescript does correctly infer the type of the property, but not its parent object.
📃 Motivating Example
The following example is very common in data oriented design.
interface Type1 { list: string[] }
interface Type2 { list: { [key: string]: string } }
declare const obj: Type1 | Type2;
if(Array.isArray(obj.list)) {
const list: string[] = obj.list; // WORKS
const map: { [key: string]: string } = obj.list; // ERROR, as expected
const objCasted: Type1 = obj; // ERROR, unexpectedly
} else {
const map: { [key: string]: string } = obj.list; // WORKS
const list: string[] = obj.list; // ERROR, as expected
const objCasted: Type2 = obj; // ERROR, unexpectedly
}
The following example works and that is good because it is an equally common case in this type of design.
interface Type3 { type: 'type3', data: boolean }
interface Type4 { type: 'type4', data: string }
declare const obj2: Type3 | Type4;
if(obj2.type === 'type3') {
const objCasted: Type3 = obj2; // WORKS
} else {
const objCasted: Type4 = obj2; // WORKS
}
So I believe the type guards should work the same way. As far as I see, this does not cause any inconsistency in the language or the type system. It is an improvement without any downsides.
💻 Use Cases
See the full example.
Issue Analytics
- State:
- Created 3 years ago
- Reactions:33
- Comments:12 (4 by maintainers)
Top Results From Across the Web
Why typescript typeguard doesn't work for an internal property ...
Type 'DatabaseResponse' is not assignable to type 'MainResponse'. Types of property 'settings' are incompatible. Type 'string | null' is not ...
Read more >How to use type guards in TypeScript - LogRocket Blog
The in type guard checks if an object has a particular property, using that to differentiate between different types. It usually returns a ......
Read more >Typescript Instanceof Type Guard - TekTutorialsHub
Typescript instanceof operator checks if a value is an instance of a class/constructor function. It acts as TypeGuard & infers type in ...
Read more >Type narrowing - mypy 0.991 documentation
callable() like in callable(obj) will narrow object to callable type ... Mypy can also use issubclass() for better type inference when working with...
Read more >What are type guards in typescript? - Tutorialspoint
The 'in' type guard determines if an object contains a specific attribute, which is then used to distinguish between distinct types. It ...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
I want to take another look at this; seems like we might have the right machinery in place now
Here is a workaround for my use case:
Playground