In TypeScript, how do I access a member of a namespace without hard-coding the member name?
As an example, I have one externally defined file:
//This file (tsDemoTypes.d.ts) is externally defined
//and CANNOT BE CHANGED, but the exported 'ValidName' union
//is guaranteed to be consistent (so it can e.g. be used in a cast).
export interface Helicopter {
name: "Helicopter";
hover: (height: number, spin: boolean) => Promise<void>;
maxAirspeed: 123;
}
export interface Airplane {
name: "Airplane";
barrelRoll: (radius: number) => Promise<void>;
maxAirspeed: 600;
}
export interface Submarine {
name: "Submarine";
dive: (depth: number, twists: number) => Promise<void>;
}
export type ValidName = 'Helicopter' | 'Airplane' | 'Submarine';
and a file which uses that to try to derive and use some related types:
//This file (tsDemo.ts) can be freely changed.
import type * as Movers from './tsDemoTypes';
type Demo = Movers.ValidName; //"Helicopter" | "Airplane" | "Submarine" as expected
type ChopperWrong = Movers['Helicopter']; //Error ts(2709): Cannot use namespace 'Movers' as a type.
type Chopper = Movers.Helicopter; //Works, but only if you know the name when writing this code.
type MoverMap = {
//Simple example; more complex version adds filtering and type manipulation after this but
//if this won't work, the more complex version won't either.
[T in Movers.ValidName] : Movers[T] //Error ts(2709) as above
}
How would I build up MoverMap or otherwise dynamically access members of this imported namespace?