I have a readonly Pokemon[] array named PokemonData. Each element has a name member. Is it possible to make a type that is a concatenated list of pokemon names?
interface Pokemon {
readonly name: string;
// ...
}
const PokemonData: readonly Pokemon[] = [{
name: 'Pikachu',
// ...
}, {
name: 'Bulbasaur',
// ...
}] as const;
type PokemonName = // TODO: should be 'Pikachu' | 'Bulbasaur'
I could easily do this if I had an array of just the names:
const pokemonNames = [ 'Pikachu', 'Bulbasaur' ] as const;
type ArrayType<T> = T extends readonly (infer U)[] ? U : never;
type PokemonName = ArrayType<typeof pokemonNames>;
I suspect, if this is possible at all, I need the object-property equivalent of my ArrayType<T> above and/or a function that takes in a Pokemon and returns its name.
// using a type approach (doesn't work)
type GetPokemonName<T extends Pokemon> = T['name'];
type GetPokemonNames<T> = T extends Pokemon[] ? GetPokemonName<T[/* something here */]> : never;
// using a function approach (may work, but I don't know how to convert it to a type)
function getPokemonName(pkmn: Pokemon) {
return pkmn.name;
}
I also thought maybe the ReadonlyArray<T>.map() would be useful, but it just returns a string type.
const pokemonNames = PokemonData.map(p => p.name); // using 'as const' throws a compile-time error
type PokemonName = ArrayType<typeof pokemonNames>;