TypeScript Type Guard Oddity

I use TypeScript protection in a ternary statement in a loop and see a behavior that I don't understand.

My interfaces

interface INamed { name: string; } interface IOtherNamed extends INamed { otherName: string; } 

Protection of my type

 function isOther(obj: any): obj is IOtherNamed { ... // some check that returns boolean } 

General usage example

 var list: Array<{named: INamed}> = []; for(let item of list) { var other: IOtherNamed = ... } 

Inside my for .. loop, I use my guard type to assign my current element or null to the IOtherNamed variable.

This does not work

 // Compiler Error: INamed is not assignable to IOtherNamed for(let item of list) { var other: IOtherNamed = isOther(item.named) ? item.named : null; } 

It does

 for(let item of list) { var named: INamed = item.named; var other2: IOtherNamed = isOther(named) ? named : null; } 

My questions

  • Is it by design that one of them works and the other does not?
  • If by design, what nuance here determines when it works or not? In particular, why does disabling my object of a new variable (without any type change) get rid of a compiler error?
+6
source share
1 answer

Yes, this is by design for TypeScript <2.0:

Note that the type of protection affects only the types of variables and parameters and does not affect the members of objects, such as properties.

- 4.20 of the language specification ( PDF , p. 83)

Therefore, the reason it works in the second scenario is because you assigned the property to a variable, and then enter the protected variable.

Update:. As Alex noted, TypeScript 2.0 will support property protection types.

+4
source

All Articles