0

Essentially, I want a way to ensure that an options argument has keys which are the values of a specific enum:

//enum Mode { Foo, Bar };
interface Mode { Foo: number, Bar: number }

interface View { 
    text: string;
};

class FooView implements View {
    text = 'foo';
 }

class BarView implements View { 
    text = 'bar';
}

function initialize(options: { mode: {[P in keyof Mode]?: View} }) {
    let mode: View = options.mode.Foo;
}

initialize({ mode: { Bar: new FooView() } });

It works perfectly if I use an interface/class instead of enum, but this is truly an enum (conceptually)...

See this playground

1 Answer 1

0

Keys have to be either strings or numbers. You can kind of do this, but you have to use the bracket syntax and set your object's key as a number:

enum Mode { Foo, Bar };

function initialize(options: { mode: {[key:number]: View} }) {
    let mode: View = options.mode[Mode.Foo];
}

initialize({ mode: { [Mode.Bar]: new FooView() } });

The idea for this answer comes from Sohnee's answer to a similar question.

Obviously the caveat here is that someone could just as easily do something like

initialize({ mode: { [999]: new FooView() } });

Less than optimal. The best you could do there is throw an error at run time if the value is not a valid Mode:

if (!Object.keys(options.mode).every((key) => key in Mode)) {
    throw new Error("Nice try");
}
Sign up to request clarification or add additional context in comments.

1 Comment

I was thinking along those lines... Definitely less than optimal. Thanks for the info!

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.