2

I've been trying to make a type whose indexer has a return type which is based upon a string literal for the key.

export enum Units {
    Enum = 'enum',
    String = 'string',
    Boolean = 'bool',
    Pounds = 'pounds'
}

export type AConditional<T extends Units> = T extends 'string' ? string : T extends 'bool' ? boolean : number;

type AType = {
    <T extends Units>[Key in `${string}/${T}`]: AConditional<T>;
}

I'm aiming for

const a: AType = {};
typeof a['whatever/pounds'] === 'number'
typeof a['something/bool'] === 'boolean'
typeof a['something/string'] === 'string'
a['something/notaunit'] //Error
a['wrong key'] //Error

The only part I have been unable to solve is how to add generics to an object indexer, obviously adding it before the brackets like I have in the snippet does not work, and putting it in the type's generics does not work either because then the object must have a generic which does not work for my case. Does anyone know any solutions to make it work as shown above?

1
  • You can't add generics to an object indexer. Why can't you do AType<"whatever/pounds"> === "number"? Commented Apr 11, 2022 at 17:40

1 Answer 1

2

You were pretty close, but a relatively new feature of TypeScript is using as in mapped types to "rename" keys:

type AType = {
    [T in Units as `${string}/${T}`]: AConditional<T>;
};

And because Units is just an enumeration, we can use T in Units directly.

Playground

Sign up to request clarification or add additional context in comments.

Comments

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.