5

I have a case where i need to use conditional types in Typescript. I'm not 100% sure that it's possible to do this using my approach, but I believe there must be a way.

I have simplified my code in the example below.

type Friend = {
    phoneNr: number;
};

type Enemy = {
    howToAvoid: string[];
};

interface Names {
    edward: Friend;
    sam: Enemy;
}

const names: Names = {
    edward: {
        phoneNr: 1234,
    },
    sam: {
        howToAvoid: ["don't go there", "dont do that"],
    },
};

function select<T extends keyof typeof names>(arg: T): Friend | Enemy {
    return names[arg];
}

console.log(select("edward"));

In short, the function select() accepts only the 2 arguments (edwards and sam) which are the keys of names. names contains a list of people, who can either be an Enemy or a Friend. select() can either return an object of type Enemy or Friend. I know it's one of the two, but I don't know which one it is.

What I want, is to be able to know that select("edward") will always return an object of type Friend, and that select("sam") will always return an object of type Enemy. All that assuming that I know in advance who is a friend, and who is an enemy.

Can we do that?

To illustrate, (by mixing the TS and JS syntaxes) I want to do the following:

function select<T extends keyof typeof names>(arg: T): T==="edwards" ? Friend : Enemy {
    return names[arg];
}

Many thanks!

1

1 Answer 1

4

You can look up the argument as a property in the type:

function select<T extends keyof typeof names>(arg: T): Names[T] {
Sign up to request clarification or add additional context in comments.

2 Comments

Works great, didn't think of that. Thanks!
...or more consistently function select<T extends keyof Names>(arg: T): Names[T] {//...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.