Phoen1xx
@Phoen1xx

Почему reject возвращает тип unknown?

Здравствуйте. Подскажите пожалуйста, я пытаюсь обернуть fetch функцией, для более удобной работы с json:
interface ResponseData{
    status: boolean;
    data?: object;
}

function sendQuery(url: string, data: object): Promise<ResponseData>
{
  return fetch(url, {
    method: "POST",
    headers: {
      Accept: "application/json",
      "Content-Type": "application/json"
    },
    body: JSON.stringify(data)
  }).then((response: Response) => {
    return response.json();
  }).then((data) => {
      return new Promise((resolve, reject) => {
        resolve({
            status: true,
            data: data
        });
      });
  }).catch(() => {
      return new Promise((resolve, reject) => {
          reject({
            status: false
          });
      });
  });
}


Появляется ошибка:
Type 'Promise<unknown>' is not assignable to type 'Promise<ResponseData>'.

Эта ошибка появляется из-за блока catch, почему-то ts считает что вернется Promise(unknown). Пробовал interface менять на type. Указывать тип у функции catch не помогает.
P.S. Указывать костыль в виде Promise(any) не кажется верным решением.
  • Вопрос задан
  • 88 просмотров
Пригласить эксперта
Ответы на вопрос 2
lazalu68
@lazalu68
Salmon
Такое происходит потому что у вас функция неправильно организована: вы утверждаете что sendQuery у вас вернёт промис, но на самом деле возвращаете промис (return fetch), который вернет промис в котором ResponseData. Если вы хотите вернуть промис, то вы либо 1) возвращаете исходный, тот который вам вернул fetch и остальные методы в цепочке, либо 2) возвращаете созданный вами, вот как в примере с асинхронным delay:

function delay(duration: number): Promise<any> {
    return new Promise(res => setTimeout(res, duration))
}
Ответ написан
Aetae
@Aetae
Тлен
Понавертели лишнего.
Во-первых: есть хэлперы Promise.reslove(data) и Promise.reject(error), а во-вторых: при возврате из then\catch даже они не нужны.
interface ResponseData {
  status: boolean;
  data?: object;
}

function sendQuery(url: string, data: object): Promise<ResponseData> {
  return fetch(url, {
    method: "POST",
    headers: {
      Accept: "application/json",
      "Content-Type": "application/json"
    },
    body: JSON.stringify(data)
  }).then(response => 
    response.json()
  ).then(data => ({
    status: true,
    data: data
  })).catch(() => {
    throw {
      status: false
    }
  });
}


Хотя ваш вариант НЕ неправильный, просто бессмысленно перегруженный, проблема в том, что TS, увы, не может автоматически вывести тип конструкции new Promise, а потому выдаёт Promise<unknown>. Т.е. каждый раз, когда вы используете new Promise - надо использовать его с дженериком: new Promise<Type>.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы