in JavaScript I often (ab)use objects as pseudo-enums:
const application = {
    ELECTRIC: {propA: true, propB: 11, propC: "eee"},
    HYDRAULIC: {propA: false, propB: 59, propC: "hhh"},
    PNEUMATIC: {propA: true, propB: 87, propC: "ppp"},
}
const foo = application.ELECTRIC
const bar = application.HYDRAULIC
I'd like to achieve a similar behavior in TypeScript, but in a type-safe manner. Here's what I have so far:
type Application = "ELECTRIC" | "HYDRAULIC" | "PNEUMATIC";
interface ApplicationProps {
  propA: boolean;
  propB: number;
  propC: string;
}
const application: Record<Application, ApplicationProps> = {
    ELECTRIC: {propA: true, propB: 11, propC: "eee"},
    HYDRAULIC: {propA: false, propB: 59, propC: "hhh"},
    PNEUMATIC: {propA: true, propB: 87, propC: "ppp"},
}
const foo = application.ELECTRIC;
---
let bar: ApplicationProps; // an attempt to restrict bar to application.ELECTRIC|application.HYDRAULIC|application.PNEUMATIC
bar = application.HYDRAULIC;
That works okay but feels clumsy.
1) There seems to be lot of repetition in type/interface/object
Is there some TS-Trickery to automatically infer type Application / interface ApplicationProps from the object? Like some keyof typeof something magic?
2) It feels strange to type bar as ApplicationProps when I actually want to restrict it to members of application
Is there a more elegant way to restrict bar to application.ELECTRIC|application.HYDRAULIC|...?
3) If I want to define bar in another file, I need to import ApplicationProps and application. I know the type info is part of application but I don't know how to get it.
The best I got so far was: let bar: typeof application[keyof typeof application]
Which of course is stupid. There has to be a better way?!
Thanks in advance :)
constassertion for the enumlike object, and a type alias of the formtype Enum = typeof Enum[keyof typeof Enum]for the type. Like this in your case. Does that meet your needs? If so I could write up an answer; if not, what am I missing? I might have just written this up directly, but your line "which of course is stupid" gives me pause, given that the "stupid" thing is part of my suggestion. Can you articulate why it's stupid?