Почему я получаю ошибку типа TypeScript у этого подписчика с эффектом Effector? - PullRequest
0 голосов
/ 01 апреля 2020

Я работаю над внешним приложением, использующим React, Typescript, Effector, FetchAPI и другие. Я создал эффект Effector для удаления элемента из моего бэкэнда:

export const deleteItemFX = createEffect({
  handler: (id: string) => {
    return fetch(itemUrl + id, {
      method: "DELETE",
    });
  }
})

Теперь в своем компоненте React я импортирую свой эффект и добавляю подписчика в его событие finally согласно документации:

deleteItemFX.finally.watch(({params, status, result}) => {
    console.log('finally.watch called');
    if (result.ok) {
      result.json().then(() => {
        message.success(t("delete_item.success"));
      })
    }
  });

Мой код не компилируется из-за следующей ошибки типа:

Property 'result' does not exist on type '{ status: "done"; params: string; result: Response; } | { status: "fail"; params: string; error: Error; }'.  TS2339

Кто-нибудь знает, что я могу сделать, чтобы получить «результат» моего обработчика в моем «finally.watch» 'функция?

1 Ответ

0 голосов
/ 01 апреля 2020

Проблема заключается в том, что вы пытаетесь извлечь свойство result при деструктурировании аргумента до watch, прежде чем проверять, равно ли status "done" или "fail".

Посмотрите на сообщение об ошибке: свойство result не существует для типа:

{ status: "done"; params: string; result: Response; }
| { status: "fail"; params: string; error: Error; }

Это объединение двух типов объектов; Чтобы прочитать свойство из объединения, это свойство должно существовать на обеих сторонах объединения. result существует только в первом случае, а не во втором. Поэтому, прежде чем пытаться прочитать его, необходимо убедиться, что данные, которые у вас есть, относятся к первому случаю. Вы делаете это с помощью оператора if для уточнения типа:

deleteItemFX.finally.watch(response => {
    console.log('finally.watch called');
    if (response.status === "fail") {
        // Handle error here. TypeScript knows that we're in the
        // second case of the union type here, so response.error
        // is available inside this block
        return;
    }

    // Now TypeScript knows that we're in the first case of the union,
    // and that response.result exists, so we can read it
    if (response.result.ok) {
      result.json().then(() => {
        message.success(t("delete_item.success"));
      })
    }
  });
...