Декодирование JSON с использованием fetch и TypeScript вызывает ошибку «Ожидается, что будет возвращено значение в конце функции стрелки» - PullRequest
0 голосов
/ 29 апреля 2020

У меня есть следующий код, который пытается выполнить AJAX -запрос, а затем декодировать полезную нагрузку, поддерживая типы до конца:

export function fetchJson<T>(url: string, data: FetchDataTypes): Promise<T> {
    return new Promise((resolve, reject) => {
        fetch(url, {})
            .then((response: Response) => {
                if (!response.ok) {
                    reject(response);
                } else {
                    return response.text() as Promise<string>;
                }
            })
            .then((text: string) => {
                try {
                    resolve(JSON.parse(text) as T);
                } catch (err) {
                    reject(err);
                }
            })
            .catch((err: Promise<void>) => reject(err));
    });
}

Проблема в том, что eslint выдает эту ошибку:

Ожидается, что будет возвращено значение в конце стрелки. Функция constant-return

Я посмотрел документацию и уверен, что это так, потому что первый .then обратный вызов имеет несоответствие в возврате / отсутствии возврата. Я пытался изменить свой код, чтобы получить возврат или нет, но я не могу понять, как переписать этот код, чтобы снова сделать eslint счастливым.

Все связанные вопросы, которые я мог найти, были ошибками где разработчик забыл вернуться из методов картографирования et c, и я не смог найти их относящиеся к моему сценарию.

Редактировать: Просто чтобы прояснить, я хочу иметь возможность вызывать мою функцию следующим образом:

export const fetchSomeObject = (): Promise<SomeResponseType> =>
  fetchJson('/api/some-endpoint', {
    method: 'GET',
    headers: {},
  });

А затем:

fetchSomeObject.then((response: SomeResponseType) => {
  [...]
});

Ответы [ 2 ]

1 голос
/ 29 апреля 2020

Хотя вы могли бы исправить это, всегда return вводя и настраивая .then logi c, было бы гораздо лучше полностью избежать явного построения антипаттерна Promise , полностью обойдя проблему. Когда в Обещании есть ошибка, вы можете throw внутри него остановить обработчик и сделать поток управления go на catch.

Вы должны catch в получателе из fetchJson - не catch здесь, потому что тогда, когда выборка не удалась, вы будете возвращать что-то неправильного типа - когда вы catch, вы возвращаете resolved Обещание, что здесь нежелательно.

Если вы хотите JSON.parse ответ, используйте метод .json(), а не метод .text(), и это будет сделано автоматически.

Также обратите внимание, что нет необходимости явно указывать типы, когда TS уже может это сделать.

export function fetchJson<T>(url: string): Promise<T> {
    return fetch(url)
        .then((response) => {
            if (!response.ok) {
                throw new Error(response.statusText);
            } else {
                return response.json();
            }
        });
}

// Then in the consumer:
fetchJson<someType>('someURL')
    .then((result) => {
        // result is of type someType
    })
    .catch((err) => {
        // handle errors here
    });
0 голосов
/ 29 апреля 2020

Первое .then не разрешается, если ответ 200 OK - попробуйте изменить его на ниже:

export function fetchJson<T>(url: string, data: FetchDataTypes): Promise<T> {
    return new Promise((resolve, reject) => {
        fetch(url, {})
            .then((response: Response) => {
                if (!response.ok) {
                    reject(response);
                } else {
                    resolve(response.text() as Promise<string>);
                }
            })
            .then((text: string) => {
                try {
                    resolve(JSON.parse(text) as T);
                } catch (err) {
                    reject(err);
                }
            })
            .catch((err: Promise<void>) => reject(err));
    });
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...