Nisha Patel
Problem
I can easily use a constant string value to narrow down a union type:
Here there are only two cases:
value.type is the constant "type1"
value.type is the constant "type2"
But what if I expand T, allowing payload to be either a single item or an array? Now there are 4 possibilities:
value.type is "type1" and value.payload is not an array
value.type is "type1" and value.payload is an array
value.type is "type2" and value.payload is not an array
value.type is "type2" and value.payload is an array
Here is an example:
Why is typescript only partially narrowing down the type, and how can I achieve fully narrowed values for the 4 cases?
EDIT: Looks like multiple conditions in the if is irrelevant; typescript struggles to narrow based on Array.isArray alone:
Solution
You are trying to treat T as a >discriminated union, but the payload property is not recognized as a discriminant. For a property to be seen as a valid discriminant, it must contain unit/>literal types. Your type property is valid because "type1" and "type2" are string literal types. But arrays and your Payload types are object types, not literal types. So you can't check value.payload and have it narrow the apparent type of value itself.
Note that Array.isArray(value.payload) does act as a type guard on the value.payload property, but because the property is not a discriminant, this narrowing does not propagate up to the value itself. There is an open feature request at >microsoft/TypeScript#42384 to allow property type guards to propagate up to containing objects. It's not part of the language yet, though, and previous requests for it were declined as it was considered too expensive to synthesize new types for every type guard check on a nested property.
For now, if you want to get behavior like this you could write a >custom type guard function that narrows a value based on whether its payload property is an array. Like this:
Then instead of writing Array.isArray(value.payload) inline, you call hasArrayPayload(value):
Suggested blogs:
>How to Select checkboxes on an HTML treeview with JavaScript?
>How to use querySelectorAll()" with multiple conditions in JavaScript?
>How to fix mouseover event glitch in JavaScript?
>How to do light and dark mode in a website using HTML and JavaScript?
>How to manipulate manipulating Array object in JavaScript?
>How to merge an object into Array with the same key in JavaScript?
>Javascript Error Solved: Property 'id' does not exist on type 'T'
>Why highlighted table row using class not working in JavaScript?
>How to rename an object key based on the condition in JavaScript?
>How to sort an array based on another array in Javascript?
>Javascript: Modal not closing with a button