How to change a function's parameter type based on the current input?

Viewed 40

i want to do something like trpc does on the router.query and router.mutation methods.

i have a method called createProcedure that accepts an object with 2 props:

  • one is a validation schema
  • other is a resolver, that receives an object with the output of the validated schema (the property name is input)

and returns a function that accepts an object with the same signature as the resolver.

i want the resolver to hint the input property only if a schema is provided. i want the returned function to allow an input property only if the procedure has a defined schema.

here is a ts playground with my attempt on getting it done, and also pointing the issues that i had.

edit 1: here is a ts playground link with an attempt using union types

1 Answers

Here is how to change a function's parameter type based on the current input. You need to use union types.

Classically, I use a type property to switch between union types easily.

type InputProps = {
    type: "text"
    text: string;
} | {
    type: "date";
    date: Date;
} | {
    type: "color";
    color: Color;
};

But in your case, it is still possible to have types that don't have to share a property. Here is the complete example that uses undefined to do the type check.

type DifferentProps = {
    event: number;
} | {
    event?: undefined;
    input: number;
};
function acceptDifferent(props: DifferentProps) {
    if (props.event === undefined) {
        console.log(props.input); // number: number
    } else {
        console.log(props.event); // event: number
    }
}
// valid
acceptDifferent({input: 1})
// valid
acceptDifferent({event: 2})
// invalid
acceptDifferent({event: 3, input: 4})

Edit to answer the edit. Here is the example

Related