Основная идея
Функция разрушения вызывает что-то более безопасное для синтаксического анализа.
Модель (типы TS):
По дизайну только с одним аргументом:
interface Func {
func: string;
arg: Func | string;
}
С несколькими аргументами:
interface Func {
func: string;
args: Array<Func | string>;
}
Варианты реализации
1. Изменение структуры объекта
Только один аргумент:
{
func: "paramaters",
arg: {
func: "lookup",
arg: "lookup1"
}
}
Несколько аргументов:
{
func: "paramaters",
args: [{
func: "lookup",
args: ["lookup1"]
}]
}
2. Без изменения структуры, используя JSON.parse
:
Используйте тот же подход со строкой JSON.
{
type: 'move',
value: "{ \"func\": \"parameters\", \"args\": [ \"bar\" ] }",
},
Таким образом, вы можете получить его с помощью: JSON.parse(actions[0].value)
.
Запуск функции (JSON опция)
В качестве примера окончательного выполнения у вас может быть словарь разрешенных функций:
const parameters = (...args) => console.log(...args);
const lookup = (arg) => console.warn(arg);
const allowedFunctions = {
parameters,
lookup,
};
И некоторые помощники для проверки и запустите их:
const isFunction = (functionCall) =>
functionCall.hasOwnProperty("func") &&
functionCall.hasOwnProperty("args") &&
Array.isArray(functionCall.args);
const runFunction = (functionCall) => {
const func = allowedFunctions[functionCall.func];
if (!func) {
throw new Error(`Unknown function: ${functionCall.func}`);
} else {
const args = functionCall.args.map((arg) => {
if (isFunction(arg)) {
return runFunction(arg);
}
return arg;
});
return func.apply(null, args);
}
};
Таким образом, основной вызов может выглядеть так:
for (const action of actions) {
if ("string" === typeof action.value) {
try {
const value = JSON.parse(action.value);
if (isFunction(value)) {
console.log("Function returns:", runFunction(value));
} else {
throw new Error("Not a function object");
}
} catch (ex) {
console.error("Not a function or unknown", ex);
}
}
}
Эти функции не являются окончательными, вы бы хотели добавить дополнительные проверки или другие возможные значения, которые потребуют дальнейшего анализа, но я надеюсь, что основная идея остается ясной.