I have a function that accepts an object with query arguments. A simplified example of query args is below. I want to ensure any values in sortBy
are present in fields
. I can check this at runtime but I am wondering if it is possible to do this with TypeScript.
const validQueryArgs = {
fields: ['a', 'b', 'c'] as const,
sortBy: ['a'] as const
};
const invalidQueryArgs = {
fields: ['a', 'b', 'c'] as const,
sortBy: ['d'] as const // ts error here would be great :)
};
I know you can do something along the lines of this (Matt Pocock has a youtube short about this):
function createQueryArgs<T>({sortBy, fields}: { sortBy: NoInfer<T>, fields: T[] }): {fields: T[], sortBy: T } {
return {
fields,
sortBy
}
}
const someArgs = createQueryArgs({
sortBy: "c", // error here :thumbs-up:
fields: ["a", "b"] as const
})
Is there any way I can do this without using a pass-through function?
I tried going down a conditional types road but hit a dead-end pretty quickly.
type CheckQueryArgs<T> = T extends { fields: infer Fields, sortBy: infer SortBy } ?
SortBy extends Fields ?
true :
never :
never
type CheckInvalid = CheckQueryArgs<typeof invalidQueryArgs> // never :thumbs-up:
type CheckValid = CheckQueryArgs<typeof validQueryArgs> // never :thumbs-down:
???? TypeScript playground
Thank you!