#type narrowing not working as expected

21 messages · Page 1 of 1 (latest)

lean deltaBOT
#

@buoyant mason Here's a shortened URL of your playground link! You can remove the full link from your message.

mis#0279

Preview:ts // ignore this type Position = {} type VarType = {} type ValueResult = { type: 'ValueResult' } type EnumStructResult = { type: 'EnumStructResult' } type UnknownValueResult = { type: 'UnknownValueResult' } type InvalidResult = { type: 'InvalidResult' } type UnknownArrayDimension = { type: 'UnknownArrayDimension' } ...

quaint crescent
#

typescript does have discriminated unions (narrowing based on literal properties)...

#

... but the narrowing doesn't go up a level

#

and so narrowing happens on the union in the first variant's size, but it doesn't continue outwards to the outer union (directly under type ArrayResult)

buoyant mason
#

mmm ok, so what should i do then, i dont think i should use runtime assertions

#

i could use Array.isArray i guess, but its adding unnecessary code to the runtime, maybe cast it with the as keyword?

quaint crescent
#

yeah i guess

lean deltaBOT
#
n_n#2622

Preview:ts ... type AnyResult = | ValueResult | EnumStructResult | UnknownValueResult | InvalidResult function sizeTypeIs<T extends AnyResult["type"]>( result: ArrayResult, type: T ): result is Extract<ArrayResult, {size: {type: T}}> { return result.size.type === type } ...

quaint crescent
#

another way is creating a helper function

#

it's a bit weird creating a helper function for this specific example

#

the benefit of it is when you need to check .size.type quite often

#

so you don't accidentally as as the wrong type

quaint crescent
# lean delta

but note that this specific function signature requires splitting ArrayResult further (see the playground for more info)

dreamy ginkgo
#

If you can change the underlying structure, "flattening" the .size.type into something like .sizeType would work

lean deltaBOT
#
Retsam19#2505

Preview:ts // ignore this type Position = {} type VarType = {} type ValueResult = { type: 'ValueResult' } type EnumStructResult = { type: 'EnumStructResult' } type UnknownValueResult = { type: 'UnknownValueResult' } type InvalidResult = { type: 'InvalidResult' } type UnknownArrayDimension = { type: 'UnknownArrayDimension' } ...

buoyant mason
# lean delta

yeah i guess i could do that, tho im just checking the size type once or twice, no more

quaint crescent
#

yeah in that case as is probably your best option

buoyant mason
#

so i would have duplicated state, or whatever its called, and thats not good

dreamy ginkgo
#

@buoyant mason Well you'd flatten out those other fields, too.