#Help with asserting value is not undefined.

26 messages · Page 1 of 1 (latest)

fallen surge
#

I am checking in a higher block if a value is undefined or not and storing this in a const. However using this const later doesn't appear to be asserting the type.

This is a simplified example, in the actual code the check is used in many different places in the component.

delicate breachBOT
#
hailwood#0

Preview:```ts
...
const hasSelectedValue =
range !== undefined &&
range.from !== undefined &&
range.to !== undefined

if (hasSelectedValue) {
return (
formatISO(range.from) +
" - " +
formatISO(range.to)
)
}
...```

wheat yarrow
#

You can either check the actual value in the check, or you put the check into a function, which sometimes will do what you want

plain wolf
#

TS doesn't 'remember' what narrowing a certain boolean implies - instead of using booleans it can be useful to use NarrowedValue | undefined

#

In this case that would look like:

 const nonNullRange =
  range && range.from && range.to
    ? { from: range.from, to: range.to }
    : undefined;

if (nonNullRange) {
  return formatISO(nonNullRange.from) + " - " + formatISO(nonNullRange.to);
}
wheat yarrow
#

TS Playground is having real trouble with the types in that playground for me. Any better for you Retsam?

#

oh now it's alive

plain wolf
#

Yeah, kinda looks like react-day-picker is spawning a bunch of errors that is messing up the ability to resolve types

delicate breachBOT
#
sandiford#0

Preview:```ts
import {DateRange} from "react-day-picker"
import {formatISO} from "date-fns"
import {useState} from "react"

type ValidDateRange = {
from: Date
to: Date
}

function hasSelectedRange(
range: DateRange | undefined
): range is ValidDateRange {
return (
range !== undefined &&
range.from !== undefined &&
range.to !== undefined
)
...```

wheat yarrow
wheat yarrow
#

Sometimes TS will infer the return assertions for this automatically, I seemed to need to do it manually here

plain wolf
#

It only infers retun types for type-guards when you pass a callback to something typed as accepting a type-guard

wheat yarrow
#

ah really

#

for performance reasons?

plain wolf
#

Probably, yeah.

wheat yarrow
#

maybe we should have a(): infer predicate option

plain wolf
#

Yeah, I've considered that, though I think the inferring callbacks covers like 90% of the cases anyway.

wheat yarrow
#

Hmm I use this type of type guard a lot. Rarely use .filter etc

plain wolf
#

I wouldn't use one here and wouldn't recommend it

#

It's not typesafe or honestly that convenient.

wheat yarrow
#

I guess the reason for this code is to avoid rechecking. So for that you'd need something like your suggestion

plain wolf
#

Yeah, my preference order here is probably:

  1. Just inline the check (can drop !== undefined to make it less verbose)
  2. Use the NarrowedValue | undefined pattern (useful if it's repeated)
  3. 🤷‍♂️ just ! and it's pretty clear why it's okay to assert in context.
wheat yarrow
#

I used type guards a lot when making my JSX framework and needing to be able to narrow down Nodes to the specific type often

#

A Node being a primitive or object, or array, and the object could be an HTML el, a function component or a class components. So the checks to identify which get a bit onerous.

#

Would be nice if the assertion was typesafe though. I wonder if there is any value in comparing the inferred predicate to the stated predicate. But should pretty stop OTing the thread now