You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
TypeScript Version: 2.1.5
Also works on typescript playground
Code
type typedActions =
{ type: "action1", a:string }
| { type: "action2", b:string }
let typeGuard = function (action): action is typedActions {
return true
}
let broken = function(action) {
if (typeGuard(action)) {
// we typeguard action to typedActions
switch (action.type) {
case "action1":
// we didn't typeguard down to action1 :(
console.log(action.a)
break
case "action2":
console.log(action.b)
break
}
}
}
let works = function(action) {
if (typeGuard(action)) {
// what is this doing?
let myAction = action
switch (myAction.type) {
case "action1":
// discriminated union pattern works!
console.log(myAction.a)
break
case "action2":
console.log(myAction.b)
break
}
}
}
Expected behavior:
When action is typeguarded to typedActions using the typeGuard function, we should be able to do a discriminated union over type, meaning that accessing action.a inside the case statement should work.
Somehow, simply copying over let myAction = actioninside of the typeguard makes the code work (see second function).
Actual behavior:
There is a type error that action doesn't have property a.
The text was updated successfully, but these errors were encountered:
This is a design limitation in the control flow analyzer. We only narrow discriminated union types when the declared type of a variable is a union type. In this case, the declared type of action is any (because it has no type annotation) and therefore we don't narrow it. When you introduce a temporary variable, we infer the declared type of myAction to be typedActions and thus discriminated union narrowing works.
It would be nice not to have this limitation, but it would require more dependency reasoning in the control flow analyzer than we currently do.
TypeScript Version: 2.1.5
Also works on typescript playground
Code
http://www.typescriptlang.org/play/index.html#src=type%20typedActions%20%3D%0D%0A%20%20%20%20%7B%20type%3A%20%22action1%22%2C%20a%3Astring%20%7D%0D%0A%20%20%20%20%7C%20%7B%20type%3A%20%22action2%22%2C%20b%3Astring%20%7D%0D%0A%0D%0Alet%20typeGuard%20%3D%20function%20(action)%3A%20action%20is%20typedActions%20%7B%0D%0A%20%20%20%20return%20true%0D%0A%7D%0D%0A%0D%0Alet%20broken%20%3D%20function(action)%20%7B%0D%0A%20%20%20%20if%20(typeGuard(action))%20%7B%0D%0A%20%20%20%20%20%20%20%20%2F%2F%20we%20typeguard%20action%20to%20typedActions%0D%0A%20%20%20%20%20%20%20%20switch%20(action.type)%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20case%20%22action1%22%3A%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20we%20didn't%20typeguard%20down%20to%20action1%20%3A(%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20console.log(action.a)%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20break%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20case%20%22action2%22%3A%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20console.log(action.b)%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20break%0D%0A%20%20%20%20%20%20%20%20%7D%0D%0A%20%20%20%20%7D%0D%0A%7D%0D%0A%0D%0Alet%20works%20%3D%20function(action)%20%7B%0D%0A%20%20%20%20if%20(typeGuard(action))%20%7B%0D%0A%20%20%20%20%20%20%20%20%2F%2F%20what%20is%20this%20doing%3F%0D%0A%20%20%20%20%20%20%20%20let%20myAction%20%3D%20action%0D%0A%20%20%20%20%20%20%20%20switch%20(myAction.type)%20%7B%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20case%20%22action1%22%3A%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F%20discriminated%20union%20pattern%20works!%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20console.log(myAction.a)%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20break%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20case%20%22action2%22%3A%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20console.log(myAction.b)%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20break%0D%0A%20%20%20%20%20%20%20%20%7D%0D%0A%20%20%20%20%7D%0D%0A%7D
Expected behavior:
When
action
is typeguarded totypedActions
using thetypeGuard
function, we should be able to do a discriminated union overtype
, meaning that accessingaction.a
inside the case statement should work.Somehow, simply copying over
let myAction = action
inside of the typeguard makes the code work (see second function).Actual behavior:
There is a type error that action doesn't have property a.
The text was updated successfully, but these errors were encountered: