Ошибка при вызове объекта ссылок на функции - PullRequest
0 голосов
/ 13 июля 2020

У меня примерно так:

const fn1 = (param1: string, param2: string, param3: string): Promise<void> => {return new Promise()}

const fn2 = (param1: string, param2: string): void => {return}

const options = {
  option1: fn1,
  option2: fn2,
  option3: fn1,
  option4: fn2,
}

const myOption = 'option1';
const myParam1 = 'a';
const myParam2 = 'b';
const myParam3 = 'c';

options[myOption](myParam1, myParam2, myParam3); // ERROR in this line

Сначала я сделал это с Javascript, но потом мне пришлось преобразовать его в TS. Линтер не обнаруживает никаких проблем, но когда я пытаюсь запустить его с ts-node, он показывает следующую ошибку:

Element implicitly has an 'any' type because expression of type 'string' can't be used to index type...[the type object here]

Как я могу ввести объект, чтобы иметь возможность вызывать функции внутри, избегая использовать переключатель / case или бесконечное else / if?

Ответы [ 3 ]

0 голосов
/ 13 июля 2020

Я не получаю эту ошибку при запуске кода с ts-node, но вы можете попробовать установить тип myOption на:

const myOption: keyof typeof options = 'option1';
0 голосов
/ 15 июля 2020

Если myOption поступает из массива строк, вы можете определить защиту типа, чтобы убедиться, что он имеет тип keyof typeof options, который является правильным типом индексации для вашего объекта options.

   function isKeyOfOptions(value: string): value is keyof typeof options {
      return options[value] !== undefined;
    }

    if(isKeyOfOptions(str))
       options[str](myParam1, myParam2, myParam3) 
       // str type in this block is "option1" | "option2" | "option3" | "option4";
0 голосов
/ 13 июля 2020

Может быть, это не лучший ответ, но сработало:

const options: Record<string, typeof fn1 | typeof fn2> = {
  option1: fn1,
  option2: fn2,
  option3: fn1,
  option4: fn2,
}

Типичный сценарий, похоже, не распознает option1, option2 ... как строки, а как перечисление.

...