我可以使用打字稿将对象键限制为枚举值吗?
Can I constrain an objects keys to an enums values using typescript?
本质上,我想要一种方法来确保选项参数具有作为特定枚举值的键:
//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() } });
如果我使用 interface/class 而不是枚举,它会完美地工作,但这确实是一个枚举(概念上)...
键必须是字符串或数字。您可以这样做,但是您必须使用括号语法并将对象的键设置为数字:
enum Mode { Foo, Bar };
function initialize(options: { mode: {[key:number]: View} }) {
let mode: View = options.mode[Mode.Foo];
}
initialize({ mode: { [Mode.Bar]: new FooView() } });
这个答案的想法来自Sohnee's 。
显然这里的警告是有人可以很容易地做类似
的事情
initialize({ mode: { [999]: new FooView() } });
不太理想。如果该值不是有效模式,您可以做的最好的事情是在 运行 时间抛出错误:
if (!Object.keys(options.mode).every((key) => key in Mode)) {
throw new Error("Nice try");
}
本质上,我想要一种方法来确保选项参数具有作为特定枚举值的键:
//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() } });
如果我使用 interface/class 而不是枚举,它会完美地工作,但这确实是一个枚举(概念上)...
键必须是字符串或数字。您可以这样做,但是您必须使用括号语法并将对象的键设置为数字:
enum Mode { Foo, Bar };
function initialize(options: { mode: {[key:number]: View} }) {
let mode: View = options.mode[Mode.Foo];
}
initialize({ mode: { [Mode.Bar]: new FooView() } });
这个答案的想法来自Sohnee's
显然这里的警告是有人可以很容易地做类似
的事情initialize({ mode: { [999]: new FooView() } });
不太理想。如果该值不是有效模式,您可以做的最好的事情是在 运行 时间抛出错误:
if (!Object.keys(options.mode).every((key) => key in Mode)) {
throw new Error("Nice try");
}