I'm trying to find a way to get a strict parameters discrimination from a function overload. Obviously my issue with this implementation is that my generic type T can be extended to anything inheriting AorB props so the error I get here is perfectly expected ('{ type: "A"; a: any; }' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'AorB'.).
What I'm looking for is a way to have a sort of <T implements AorB> so that when the parameter type equals "A", the customProps parameter is discriminated as A props.
I'm also trying to avoid resorting to use any within the function implementation parameters or as within the returns.
type A = {
a: string
type: 'A'
}
type B = {
b: string
type: 'B'
}
type AorB = A | B
function createAorB(type: A['type'], customProps?: Partial<Omit<A, 'type'>>): A
function createAorB(type: B['type'], customProps?: Partial<Omit<B, 'type'>>): B
function createAorB<T extends AorB>(type: T['type'], customProps: Partial<Omit<T, 'type'>> = {}): T {
if (type === 'A') {
return {
type,
a: customProps.a || '',
}
}
return {
type,
b: customProps.b || '',
}
}
const newA = createAorB('A')
const newB = createAorB('B')
UPDATE
If I enforce AorB as the return value:
function createAorB<T extends AorB>(type: T['type'], customProps: Partial<Omit<T, 'type'>> = {}): AorB
I get both errors Property 'a' does not exist on type 'Partial<Omit<T, "type">>'. and Property 'b' does not exist on type 'Partial<Omit<T, "type">>'. on the respective customProps.a and customProps.b lines.