Использование Aurelia Fetch прервано после обновления NPM

Я только недавно сделал npm update в моем проекте Aurelia CLI с использованием TypeScript в Visual Studio 2015. Я использую aurelia-fetch-client для звонков в мой бэкэнд Web API (.NET Core).

Это пример кода, который ранее компилировался и работал нормально:

import { autoinject } from "aurelia-framework";
import { HttpClient, json } from "aurelia-fetch-client";
import { SupportedCultureInfo } from "../../model/Resources/SupportedCultureInfo";

@autoinject()
export class ResourceService {
    constructor(private http: HttpClient) {
    }

    getSupportedCultures(): Promise<SupportedCultureInfo[]> {
        return this.http.fetch("resource/cultures").then(response => response.json());
    }
}

Ни Visual Studio, ни ReSharper не предоставляют никаких указаний в пользовательском интерфейсе редактора кода, что это не скомпилируется, однако после недавнего обновления моя сборка теперь не работает с этой ошибкой:

TS2322: Type 'Promise<Response>' is not assignable to type 'Promise<SupportedCultureInfo[]>'

Единственный обходной путь, который я нашел, - это вернуться Promise<any> вместо. Здесь я действительно хочу сделать возвращаемые классы, сопоставленные с результатом JSON, и иметь возвращаемый тип метода, который также должен быть строго типизированным Promise.

Кто-нибудь знает, что изменилось в последнее время, что может вызвать это? Это очень расстраивает.

ОБНОВИТЬ:

Это код, который я смог получить работать:

import { autoinject } from "aurelia-framework";
import { HttpClient, json } from "aurelia-fetch-client";
import { SupportedCultureInfo } from "../../model/resources/SupportedCultureInfo";

@autoinject()
export class ResourceService {
    constructor(private http: HttpClient) {
    }

    getSupportedCultures(): Promise<SupportedCultureInfo[]> {
        return this.http.fetch("resource/cultures")
            .then(response => response.json())
            .then<SupportedCultureInfo[]>((data: any) => {
                const result = new Array<SupportedCultureInfo>();
                for (let i of data) {
                    const info = new SupportedCultureInfo();
                    info.cultureCode = i.cultureCode;
                    info.name = i.name;
                    info.isCurrentCulture = i.isCurrentCulture;
                    result.push(info);
                }

                return result;
            });
    }
}

Мне пришлось сделать две вещи, которые не были очевидны сразу:

  1. Используйте обобщенную перегрузку then(), чтобы указать тип возвращаемого значения, которое я хочу использовать
  2. Явно объявить any введите для параметра JSON во втором обратном вызове, в противном случае транспортер gulp считает, что он по-прежнему типизирован как Response.

1 ответ

ОБНОВИТЬ:

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

Цепные обратные вызовы: если API resource/cultures возвращает ответ как SupportedCultureInfo[] а также getSupportedCultures() просто нужно вернуть ответ таким, какой он есть, тогда второй обратный вызов не требуется. Ответ, который я разместил ранее, будет достаточным.

Я предполагаю, что второй обратный вызов, скорее всего, требуется в любом из этих двух случаев (или по какой-то другой причине)

  1. API возвращает другой тип, который должен быть сопоставлен SupportedCultureInfo[]
  2. Ответ API требует дальнейшей обработки перед отправкой getSupportedCultures()

Если вам требуется второй обратный вызов для дальнейшей обработки ответа, вам следует вызвать общий then<TResult> метод, пока вы читаете ответ как json вместо того, чтобы в более поздней части в цепи обратного вызова.

Причина сообщения об ошибке: в обновленном коде причину обрабатывает gulp транспилер data как тип Response связано с тем, что не является общим then(response => response.json()) используется который возвращает Promise<Response>,

Вместо этого используйте then<SupportedCultureInfo[]>(response => response.json()) который бы вернулся Promise<SupportedCultureInfo[]> или же then<any>(response => response.json()) который бы вернулся Promise<any>,

Используя либо then<SupportedCultureInfo[]>(response => response.json()) или же then<any>(response => response.json()) даст вам data во втором обратном вызове как SupportedCultureInfo[] или же any соответственно.

getSupportedCultures(): Promise<SupportedCultureInfo[]> {
    return this.http.fetch("resource/cultures")
        .then<SupportedCultureInfo[]>(response => response.json())
        .then(data => {
                  // data will be of type SupportedCultureInfo[]
              });
}

В качестве сигнатуры метода для then<TResult> не поврежден, должен давать строго типизированный data Название переменной.

Решение

Изменения в typescript подразумевает, что мы указываем return введите в качестве параметра типа then<TResult> обратный вызов, как показано ниже.

getSupportedCultures(): Promise<SupportedCultureInfo[]> {
    return this.http.fetch("resource/cultures").then<SupportedCultureInfo[]>(response => response.json());
}

Подробности:

Я столкнулся с той же ситуацией, когда я сделал npm update, Хотя мои первоначальные мысли были виноваты aurelia-fetch-client Я также покопался в исходном коде, чтобы внести исправление в эту проблему. Но в моем поиске я обнаружил, что typescript настоящий преступник здесь.

interface Promise<T> были некоторые изменения в способе, тогда callback обрабатывает возвращаемые типы. Теперь желаемый return тип должен быть передан как параметр типа TResult в then<TResult> Перезвоните.

Другие вопросы по тегам