-
Notifications
You must be signed in to change notification settings - Fork 152
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How should TypeBox types be used with TS type predicates? #915
Comments
@nivekh Hi, You can achieve this by using generic arguments on ValidateBody. I've added a couple of extra value function calls if you're interested. Additionally, I've updated Compile to Check (as this will be more performant than compiling each time) import { Value } from '@sinclair/typebox/value'
import { Type, Static, TSchema } from '@sinclair/typebox'
function ValidateBody<T extends TSchema>(schema: T, body: unknown): body is Static<T> {
// note: you can optionally process the value with additional value
// operations. Default, Convert and Clean are very common.
const defaulted = Value.Default(schema, body)
const converted = Value.Convert(schema, defaulted)
const cleaned = Value.Clean(schema, converted)
// note: you should use Value.Check instead of compiling the schema
// for each check. This will be more performant as compilation is
// very expensive.
return Value.Check(schema, cleaned)
}
const R = ValidateBody(Type.String(), null) // body is string If you want to keep Compile, it's recommended to use a closure to hold onto the compiled schematics. The following updates the above to use the TypeCompiler + Function closure. import { Value } from '@sinclair/typebox/value'
import { TypeCompiler } from '@sinclair/typebox/compiler'
import { Type, Static, TSchema } from '@sinclair/typebox'
function CompileSchema<T extends TSchema>(schema: T) {
const check = TypeCompiler.Compile(schema)
return (body: unknown): body is Static<T> => {
const defaulted = Value.Default(schema, body)
const converted = Value.Convert(schema, defaulted)
const cleaned = Value.Clean(schema, converted)
return check.Check(cleaned)
}
}
const ValidateBody = CompileSchema(Type.String())
const R = ValidateBody(null) // (body: unknown) => body is string Hope this helps |
I can't thank you enough for the detailed reply, that helps a ton! I came close to the generic setup you've demonstrated when I was experimenting, but I'm still learning new things about TypeScript, so I was kind of approaching it backwards, I think. I actually had a caching setup for the compiled validators which I didn't include for clarity's sake, but I'll have to play around with Value.Check instead and see if it doesn't beat the comp-and-cache approach (as I imagine it might?) Thanks again, you've been a huge help! |
If I have a TS type predicate function which is meant to generically perform a TypeBox typecheck, e.g... (minimal example)
...the final type that ends up getting 'confirmed' by the predicate is unknown.
Is there a better way to write this sort of "generic type predicate" function in tandem with TypeBox?
The text was updated successfully, but these errors were encountered: