typescript simplify a type guard
I have this code. I want the if statement to be able to verify that
validationResullt.error
is a ZodError
and validation.data
is not undefined but there doesn't seem a way to do them in one statement.
should I use as
to explicitly assert the type of validation.data
? I don't want another if statement because it would just duplicate the logic inside first if45 Replies
that is one statement
it has 1 expression inside
it will not work. validationResult.error doesn't have it's type narrowed
it can be undefined like this and if i use && then validationResult.data can be undefined
is "error" a real error?
what do you mean
an instance of
Error
as if as exception was throen
thrownI think so. I am using safe parse so it isn't throwing an exception
thrown exceptions only have 2 valid types:
any
or unknown
using parse will throw it
i know why the code is tripping
it is possible for
.error
to be any value and .data
being empty
that is why the type isnt narrowing
that is what i said
you said any so I thought you meant
any
typeyeah, it is possible
hmmm
if there's a bug in the code that does the validation, it is theorically possible to be any
but assuming it can only be a zod error or undefined, the type cant be narrowed
assuming only those 2 types, the code can run in these situations:
- data is undefined
- error is a zod error
If you know the type of what you want to get inside the if you can create a type guard function. Let me find you the doc real quick
if error is undefined and data is undefined, it will run and send undefined
handle the data being undefined separatedly
and the error being undefined separatedly
Documentation - Narrowing
Understand how TypeScript uses JavaScript knowledge to reduce the amount of type syntax in your projects.
the type is already narrowed as far as possible
i would check if the error is undefined first, then check if data is undefined
i mean, if it is a zod error
this duplicates the code hmmm
no, the oposite
wait, no, like that
also, i dont see any repeated code
I'm gonna res.json(validationResult.error) in both cases because if the data is undefined then there is definitely a zod error
no, there isnt
the type is
ZodError | undefined
in case the error is undefined, you are sending undefined
over jsonyeah but the validation itself doesn't work that way. If the
safeParse
function finds that there is data that violates constraints then it will not set data (undefined) and set error to a zodError. And vice versa if the data doesn't violate constraints
or are you saying I shouldn't assume such and still plan for it to happen?plan for it to happen, because the property's value doesn't show the type without an
undefined
imagine that, for some reason, the error is undefined and the data too, like in a case where it is optionalhmm the current way I have it is not possible but ok if types is asserting it then it's better to be prepared
exactly
also, what will you send in case the error and data are undefind?

alright there we go
now, you are guaranteed that data has something, and that the error is undefined
i know it is meh to do it this way
but it is so important to take types seriously, even when "impossible"
better to be safe than sorry later. I haven't dealt with types before this so it is a bit hard to wrap my head around
it's fine
also did you mean in the case of data and error both being undefined here?
yes
but you already answered that
gotcha
yeah both got covered
exactly
and when you check ahead, the only possible type for the error is undefined
yeah
thanks again for the help.
you too ragnar although I don't think I need a predicate for something this simple
i know it is a bad looking solution, since you need 2 if statementd
but you are welcome
there is more if statements later that check if username exists in database or passwordHash matches so don't think it did much worse
maybe I will extract them in another function or middleware to organise it more
ah, I misunderstood to question (back from a nap BTW)
you can collapse your 2 conditions into a single one.
zod.safeParse
signature looks like this according to the doc :
That means that the object you get out of it always has a success
property which can be used to collapse the union into either one of the member depending on if it's true or false. So you can use a guard close like this :
interactive example on the typescript playgroundTS Playground - An online editor for exploring TypeScript and JavaS...
The Playground lets you write TypeScript or JavaScript online in a safe and sharable way.

it works
dammit it was easy
I should've just read the docs
thanks a lot
also if I am reading that safe parse error right it is saying the method returns object with either
success : true
and data
with T
type or success: false
and error
with zodError
typeyeah
T is your schema
gotcha thanks
that is a much better answer than i could give