#Explicit Return Type from Function

6 messages · Page 1 of 1 (latest)

willow sedge
#

I have a union type of two types with similar fields, some of different types. I want to have a function take a name (name being a common field) and return the type of another field (value). Right now, it's returning the union of all types of value. If I supply A or B to test with test<A>(), it locks what the string name can be to the function, but I want to provide a string name and get the type out of it. Is that possible?

interface A {
    name: "A";
    value: number;
}

interface B {
    name: "B";
    value: string;
}

type AB = A | B;

const arr: AB[] = [
    {name: "A", value: 1},
    {name: "A", value: 2},
    {name: "B", value: "asd"}
];

function test<T extends AB>(name: T["name"]): T["value"] {
    return arr.find(t => t.name === name)!.value;
}

const asd = test("A");
dire saffron
#

@willow sedge Here's a signature that works:

function test<Name extends AB["name"]>(name: Name): Extract<AB, { name: Name}>["value"] {
    return arr.find(t => t.name === name)!.value as any;
}
#

You make it generic on the name, and then you can use that to extract the value.

#

Your version doesn't work because TS can't really infer T anywhere: it's not used directly, only indirectly via T["name"] and T["value"]

#

(Hence why it works when you explicitly tell it - the signature isn't wrong, just not inferrable)

willow sedge
#

🙏🏻 I did not know Extract was a thing. That's awesome. Thank you!