'Generics in typescript object indexers

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?



Solution 1:[1]

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

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 hittingonme