#Validating a type assertion

18 messages · Page 1 of 1 (latest)

outer night
#

I'm loading a JSON file from a remote API and I know a certain property is one of ~20 strings:

type SequenceType = "rna"|"dna"|"extended"
const i = data.sequenceType as SequenceType

How can I also check the value really matches the type? Do I need to move this type declaration data out of the type system? How? Is it something to do with keyof?

#

Validating a type assertion

sullen wind
#

!hb predicates

weak questBOT
sullen wind
#

you can make one of those

outer night
#

thanks. So I could write

type SequenceType = "rna"|"dna"|"extended"
const i = "rna" as string
export function stringIsSequenceType(s: string): s is SequenceType {
  return ["rna", "dna", "extended"].includes(s)
}
if (!stringIsSequenceType(i)) {
  // error handling
}
// continue

But I have to repeat the SequenceType list twice. Is there some way to not repeat the list?

sullen wind
#

you're also defining the array again each time here

#

you could create the array outside as a tuple/const array, and then use typeof yourArray[number] to get the elements as a union

#

that'll run into an issue with the includes, though
👇

#

!:includes

weak questBOT
#
retsam19#0
`!retsam19:includes`:

The type of Array.prototype.includes assumes that you're using the string to check something about the array. If you're trying to do the reverse, a modified type signature is useful:

function includes<S extends string>(haystack: readonly S[], needle: string): needle is S {
    const _haystack: readonly string[] = haystack;
    return _haystack.includes(needle)
}

declare const x: string;
if(includes(["a", "b", "c"], x)) {
    // x is "a" | "b" | "c"
}
outer night
#

nice! Thanks. Having to replace the includes type signature globally is a little ugly though... Is there some alternative I'm missing?

#

I guess I could manually iterate through the array in my type predicate

sullen wind
outer night
#

sorry, you're right. I mean it's a little ugly to have to remember to use include(arr, x) rather than the normal arr.includes(x)

sullen wind
#

you could use the same workaround that the shown function is using

weak questBOT
#
that_guy977#0

Preview:ts const sequenceTypes = [ "rna", "dna", "extended", ] as const type SequenceType = typeof sequenceTypes[number] export function stringIsSequenceType( s: string ): s is SequenceType { // return sequenceTypes.includes(s) const valid: readonly string[] = sequenceTy ...

outer night
#

thank you for the help! Appreciate it 😊