Make .parse an assertion function #975
Replies: 11 comments
-
To be clear, I'd also be satisfied with a function that is an assertion function on its own. |
Beta Was this translation helpful? Give feedback.
-
Thanks @JacobWeisenburger, but that's not what I was looking for. What I want is an assertion function. That means that after the function is called TypeScript knows that type of the value, for example: function isString(s: unknown): asserts s is string {
if (typeof s !== 'string') throw new Error('not a string')
}
const someValue: unknown = 'string'
// @ts-expect-error someValue is unknown
someValue.toLowerCase()
isString(someValue)
// TypeScript knows now that someValue is a string
someValue.toLowerCase() |
Beta Was this translation helpful? Give feedback.
-
@kentcdodds Glad to see your interest in Zod. You've been a huge part of my career and I always look to your blog and videos for high quality content and thoughtful guidance. 🙏
Having said that, I could imagine a method that asserts the input type like |
Beta Was this translation helpful? Give feedback.
-
Hey @scotttrinh, Thanks for the kind words! I'm glad I've been helpful to you :) If this were just for my own apps then a custom hook would be fine, but I'm thinking about using this in official Remix docs and we want to have something that feels nicer than telling people to make their own hook. Something you can add without much work. I think an |
Beta Was this translation helpful? Give feedback.
-
Basically, I'm looking for https://docs.superstructjs.org/api-reference/core#assert but I slightly prefer zod's APIs so I'd prefer to not switch 😅 |
Beta Was this translation helpful? Give feedback.
-
Ahh, I keep forgetting that we never updated the documentation when we added For the moment, I would probably steer toward using |
Beta Was this translation helpful? Give feedback.
-
Ahh. I am a big fan of |
Beta Was this translation helpful? Give feedback.
-
Wow, I did not mean to fall down this rabbit hole today. Looks like having FWIW, having it as a function is a pretty trivial implementation, but there is no way to not run the preprocess in that case without exposing some kind of special version of |
Beta Was this translation helpful? Give feedback.
-
Having a separate function that applies the preprocess is fine for my use case 👍 |
Beta Was this translation helpful? Give feedback.
-
I'm keen to replace all my I was using my own library but it's parsing offering isn't great and I've since found zod! I think three features which would be necessary to become a replacement for more everyday
I've started to use the following which handles 1. but not 2. or 3. function zAssert<Val, Type extends ZodType>(
value: Val,
type: Type,
err?: Error | ((zodErr: z.ZodError) => Error | string) | string
): asserts value is Type['_output'] {
const result = type.safeParse(value);
if (result.success) {
return;
}
const error =
typeof err === 'function'
? err(result.error)
: typeof err !== 'undefined'
? err
: result.error;
throw typeof error === 'string' ? new Error(error) : error;
} const createUser = async (name: string, age?: number) => {
const user = userType.parse({
_id: 'usr_123',
name,
age,
});
const result: any = await db.insertOne(user);
zAssert(
result,
z.object({ acknowledged: z.literal(1), insertedCount: z.literal(1) }),
new VError({ info: { result, userId: user._id } }, 'Failed to insert into db')
);
// result.acknowledged // => 1
return { success: true, user };
}; For further examples; this is the kind of assert calls I'd like to replace with zod https://github.com/richardscarrott/ok-computer/blob/master/examples/vanilla/src/index.ts Would be interested to hear if there's appetite to support the ability to optionally bypass preprocessing? |
Beta Was this translation helpful? Give feedback.
-
Damn. I wanted to switch from |
Beta Was this translation helpful? Give feedback.
-
I realize that I could do
const thing = Post.parse(JSON.parse(...))
or make a second variable, but I don't really want to do that. My use case is in Remix.Here's what I have to do now:
But some people are freaked out when they see me passing a hook call in an arguments list. So I'd prefer to be able to do this:
But currently that leaves data as
any
.Beta Was this translation helpful? Give feedback.
All reactions