I have the following code that is somewhat based on this answer to a similar question:
interface A {
type: "a";
data: string;
}
interface B {
type: "b";
data: string;
}
type Helper<T extends A | B> =
T["type"] extends A["type"] ? A :
T["type"] extends B["type"] ? B :
never;
const get = <T extends A | B>({ type }: Pick<T, "type">): Helper<T> => {
return {
type,
data: type,
} as Helper<T>;
};
const mySelected = get({ type: "a" });
console.log(mySelected);
my get
function should return an object of type A
if the first arguments type is a
and one of type B
if its first arguments type is "b".
In my code however mySelected
has the type never.
If I change the function call to get<A>({ type: "a" })
I get the correct type of A
, but I would like Typescript to figure this out on its own. Furthermore, if I change the function call to get<B>({ type: "a" })
, Typescript notices that something is wrong and complains that Type '"a"' is not assignable to type '"b"'.
.
CodePudding user response:
Bases upon the previous answer you linked:
interface A {
type: "a";
data: string;
}
interface B {
type: "b";
data: string;
}
const get = <T extends Pick<A | B, 'type'>>({ type }: T ) => {
return {
type,
data: type,
} as T extends Pick<A, 'type'> ? A :
T extends Pick<B, 'type'> ? B :
never
};
const mySelectedA = get({ type: "a" }); // const mySelectedA: A
const mySelectedB = get({ type: "b" }); // const mySelectedB: B
const mySelectedC = get({ type: "c" }); // const mySelectedC: never | Type '"c"' is not assignable to type '"a" | "b"'.(2322)