A. L
A. L

Reputation: 12639

how to return exact output type from input parameter

Given a specific input to a function, how do I ensure a specific output, instead of a union?

example:

class A {
    specifically_for_a () {
        return "A"
    }
}
class B {
    specifically_for_b () {
        return "b"
    }
}

function USE_TYPE (type : "A" | "B") {
    return {
        choices : ["A", "B"],
        get my_choice () {
            if (type === "A") {
                return new A();
            }
            else {
                return new B();
            }
        }
    }
}
const a = USE_TYPE("A");
// expecting to have only type A

enter image description here

playground:

https://www.typescriptlang.org/play?#code/MYGwhgzhAECC0G8BQ1XQgBwKbAJYDNdgwQQBPAfXwHsAnCsaACgEpEU1PasAXAV1oA7aACJYIjqgC+SGaEgwAQu06YcBIiXJU6FAEbM2yTl14DhIvRM4yZSfH0HAeuasICqAZQCiFACoAmgAK3sw8ZNjQAFyi4tAAPqKKIkaS0Nz8QiomqMAAFtREWDAxANpiIgA0SSIAupVpnADmvNAAtpT5hcBYhtk5nARhEb0AvOOxKf0DORnm0IJYAO5wrADcjQMyM5xYIBC9xjuzZlmLK4rrmznbW2m2SMBuEDzQjKPQXr6BIUwVLGsgA

Upvotes: 0

Views: 64

Answers (1)

Titian Cernicova-Dragomir
Titian Cernicova-Dragomir

Reputation: 249466

Simplest way would be to use overloads:

type UseTypeResult<T> = {
    choices : ["A", "B"],
    my_choice: T
}
function USE_TYPE (type : "A"): UseTypeResult<A>
function USE_TYPE (type : "B"): UseTypeResult<B>
function USE_TYPE (type : "A" | "B") {
    // return ....
}

Playground Link

Another option, if you have a lot of these, would be to use an interface to map from the name to the type and then index into the interface. This would reduce the amounts of overloads you need:

interface TypeMap {
    A: A,
    B: B
}
function USE_TYPE <K extends keyof TypeMap>(type : K): UseTypeResult<TypeMap[K]>
function USE_TYPE (type : "A" | "B") {
    ///...
}
const a = USE_TYPE("A");

Playground Link

Upvotes: 3

Related Questions