【问题标题】:Passing generics into Promise like Promise<T>?将泛型传递给 Promise,如 Promise<T>?
【发布时间】:2017-12-31 02:31:57
【问题描述】:

我有以下功能:

class RestService {
    public async get<T>(func: string): Promise<T> {
        var toRet = {};
        await fetch(EndPoint + func)
        .then(response => response.json() as Promise<T>)
        .then(data => {
            toRet = data;
        })
        .catch(e => {
        });

        return toRet as T;
    }
}

一切正常,但我在“数据”中得到的响应总是一个通用对象。

例如,我可能有这样的模型:

class Model
{
   string name;
}

然后像这样调用函数:

get<Model>("getmodel")

响应始终是一个通用对象,如下所示:

{name:"some name"}

据我了解,Typescript 支持泛型,Promise 接受变量类型,我唯一的想法是我不能将泛型传递给泛型?

【问题讨论】:

  • 如果响应总是一个模型,那么方法不应该是泛型的,它的返回类型应该是Promise&lt;Model&gt;。你问的是这个吗?
  • 嗯,来自端点的响应是一个 json 对象,模型只是匹配 json 对象字段。我假设 Promise 其中 T 是类将使用 json 值自动填充类的实例。
  • 所以我可能会调用 get 并期望返回类型为“AnotherModel”,但我会返回一个“对象”,其中的字段与“AnotherModel”中的变量声明匹配。 .
  • 不,它不会那样做。 response.json() 只是将 JSON 反序列化为 POJO。它不知道也不关心具体的泛型类型。而toRet as T 只是告诉 TypeScript 编译器:“相信我,对象是 T 类型的,我知道我在做什么”。
  • TypeScript 纯编译时,除非您明确编写,否则没有运行时转换/转换。

标签: json typescript generics promise


【解决方案1】:

这样写可能更好。

class RestService {
    public async get<T>(func: string): Promise<T | void> {
        return await fetch('' + func)
            .then(response => response.json() as Promise<T>)
            .then(data => {
                return data;
            })
            .catch(e => {
            });

    }
}

你也可以在操场上看到它link

这样您不必覆盖任何类型,编译器可以自行计算出所有内容。

返回类型现在是Promise&lt;T | void&gt;,因为catch 函数不返回任何内容。发生错误时,您可能有其他东西或什么都没有。

Typescript 不会转换 data 对象以匹配您自动输入的 T 类型。

例如,如果您使用get&lt;AnotherModel&gt;('modelEndpoint') 调用该方法,但端点返回Model。虽然构建时的类型会说您应该在运行时期待 AnotherModel 类型的对象,但该对象实际上将是 Model 类型的对象。

这在问题中并不清楚,但也许您的问题在于 data 是 T 类型,而不是您在之前的 then 回调中返回的 Promise&lt;T&gt;

如果是这种情况,那是因为任何作为回调发送到 then 函数的 Promise 在调用外部 then 之前首先被解析。

这意味着你的代码等价于。

.then(response => response.json().then((data) => data as T))
.then(data => {
   return data;
})

只是 Promise api 会为你处理这些。

如果你想了解更多关于 Javascript 中 Promises 的陷阱,post 非常好。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-03-04
    • 2018-03-11
    • 2016-09-20
    • 2017-10-10
    • 2015-10-05
    • 2018-03-28
    • 2016-05-20
    • 2018-07-12
    相关资源
    最近更新 更多