-
Notifications
You must be signed in to change notification settings - Fork 5
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
[Feature] Input & output type infer #4
Comments
Ah yes, I am playing with this idea. It enables quite a few data transformation scenarios, from one with a default value that you suggested to exhausive type normalization: array(string())
.or(string().map(s => [s]))
.or(set(string()).map(s => [...s])) Besides, I suppose it would help us to make proper union types with I'm not yet sure how to implement it, or what the most convenient API would be for declaring narrow input types, so let's have it sit here for a while. |
We finally solved this problem with another approach. import { object, number, string, optional, Banditype } from 'banditypes'
type Simplify<T> = T extends Object ? { [K in keyof T]: T[K] } : T;
const personSchema = object({
name: string().or(optional()),
age: number(),
profession: string().or(optional()),
})
function withDefault<Schema extends object, Inputs extends Schema, Defaults extends Partial<Schema>> (
schema: Banditype<Schema>,
inputs: Inputs,
defaults: Defaults & { [K in keyof Defaults]: K extends keyof Schema ? Schema[K] : never },
) {
const data = schema(inputs);
const result = {
...defaults,
...data,
}
return result as Simplify<typeof result>;
}
const input = { age: 12 }
const person1 = withDefault(personSchema, input, { profession: 'John Doe' });
const person2 = withDefault(personSchema, input, { name: 'John Doe', foobar: 'azerty' }); // 1
const person3 = withDefault(personSchema, input, { name: 'John Doe' });
function showName(name: string) { console.log(name) }
showName(person1.name) // 2
showName(person2.name) // 3
showName(person3.name) // 4
We hope this can help anyone which want to achieve this using banditypes =) |
Given the following snippet :
Here
Person
is :This is a correctly inferred type but it's an output type, because it's the type of the object returned by the
person
function.Let's say we have a method that post a user to an API that expect a
Person
object :It's weird to see
unknown
as input in a TypeScript project, here we could write code likecreatePerson(12)
and TS would not complain.Here we cannot type the
input
parameter viainput: Person
because the name property is not optional.But
name
should be optional because it has a default value.Here we see that the same schema has a different input and an output type.
What it can take as input is not the same as what it actually return.
We could imagine a
InferInput
type that would return the input type of a schema.Now we have a proper type for the
input
parameter.This feature has been implemented in Zod :
The text was updated successfully, but these errors were encountered: