I wanna visit the class property according the params as the following code:
class Commander {
constructor() {}
create() {}
test() {}
undo() {}
redo() {}
execute(...args): void {
const command: string = args.slice(0);
const rest: any[] = args.slice(1);
this[command].apply(this, rest);
}
}
But I got an error as below:
Cannot get this[command]
because an indexer property is missing in Commander
1.
More info you can see the flowtype try.
If I make some stupid things, and please let me know!
Thanks!!
Thanks your answer, but I wanna the code keep tidy, and I found the another solve Try. But use the any keyword, make the check no sense about the static check. – Cin
If you use any keyword that is the same as just turning flow off for anything that touches that variable.
"If you want a way to opt-out of using the type checker, any is the way to do it. Using any is completely unsafe, and should be avoided whenever possible." from Any
This is a safer way: (Try)
class Commander {
$key: "create" | "test" | "undo" | "redo";
$value: () => mixed
constructor() {}
create() {}
test() {}
undo() {}
redo() {}
execute(command, ...rest): void {
this[command].apply(this, rest);
}
}
Because the property accessor you're using could be any string, Flow thinks you're trying to use your class instance as a map. To get around this, you need to do some sort of checking of the command
variable before calling the instance methods. Here's my suggested way how to do it:
(Try)
class Commander {
constructor() {}
create() {}
test() {}
undo() {}
redo() {}
execute(...args): void {
const command: string = args.slice(0);
const rest: any[] = args.slice(1);
switch(command) {
case "test":
this.test.apply(this, rest);
break;
case "undo":
this.undo.apply(this, rest);
break;
case "redo":
this.redo.apply(this, rest);
break;
default:
throw new Error("Invalid command");
}
}
}
You could also replace the method.apply(this, rest)
syntax with method(...rest)
to keep things a little cleaner, but that's stylistic ands not very relevant to your question.