返回 Promise 的 TypeScript 类型函数

Dam*_*mon 4 webstorm typescript

我正在构建一个 ionic 应用程序,该应用程序从 iTunes 中获取 rss 提要。我能够获取 rss 提要并在我的应用程序上显示条目。

我收到此错误,想了解如何正确设置变量。

export class MyPage {
    episodes: any;

    ...


    getRssFeed() {
        this.rssProvider.getFeed(this.rssUrl)
            .then(data => {
                console.log(data);
                this.episodes = data.items;
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

rssProvider.ts

...

getFeed(rssUrl: string) {
    try {
        return new Promise(resolve => {
            this.http.get(`${this.baseUrl}?rss_url=${rssUrl}&api_key=${this.apiKey}&count=${this.count}`).subscribe(data => {
            resolve(data);
        }, error => {
           console.error(error);
        });
      });
    } catch (error) {
        console.error('Something really bad happened trying to get rss feed.');
        console.error(error);
    }
}
Run Code Online (Sandbox Code Playgroud)

如果这有任何意义,我将 WebStorm 用于我的 IDE。

这是我得到的错误:

Typescript Error:
Property 'items' does not exist on type '{}'.
Run Code Online (Sandbox Code Playgroud)

好吧,items又回来了,所以离子不知道它是什么。有没有正确的方法来声明变量,所以我没有得到红色错误提示?

感谢您的任何建议!

kub*_*ube 6

承诺类型

您首先需要定义 API 返回的类型:

type ResultType = {
  items: string[]
}
Run Code Online (Sandbox Code Playgroud)

然后,告诉 TypeScriptgetFeed返回 Promise ResultType

getFeed(rssUrl: string): Promise<ResultType>
Run Code Online (Sandbox Code Playgroud)

或者在 Promise 构造函数之后指定泛型类型:

return new Promise<ResultType>(resolve => {})
Run Code Online (Sandbox Code Playgroud)

错误处理

最后,不是直接在getFeedPromise中处理错误,而是使用 reject from Promise 直接在 Promise 中进行错误处理。

getFeed(rssUrl: string) {
  return new Promise<ResultType>((resolve, reject) => {
    this.http.get(URL_ENDPOINT).subscribe(
      data => {
        resolve(data)
      },
      error => {
        // Transform your error here if needed
        reject(error)
      }
    )
  })
}
Run Code Online (Sandbox Code Playgroud)

用法

使用承诺

getFeed()
  .then(feed => {
    console.log(feed)
  })
  .catch(error => {
    console.error(error)
  })
Run Code Online (Sandbox Code Playgroud)

使用异步/等待:

try {
  const feed = await getFeed()
  console.log(feed)
} catch (error) {
  console.error(error)
}
Run Code Online (Sandbox Code Playgroud)


Exp*_*lls 4

当您这样做时return Promise,返回类型默认为{},因此 TypeScript 认为data实际上是{}Promise接受一个通用参数,该参数是您从中获得的类型.then,因此您可以执行类似的操作Promise<{ items: any }>。您还可以创建,并且可能使用比仅用于项目interface RssResponse { items: any }更好的类型。any

return new Promise<RssResponse>(resolve => {
Run Code Online (Sandbox Code Playgroud)

但是,您根本不需要将此代码包装在 Promise 构造函数中。Observables有一个toPromise方法,所以你可以将其简化为:

getFeed(rssUrl: string) {
    return this.http.get(...).toPromise();
Run Code Online (Sandbox Code Playgroud)

...其功能应该相同。

此外,您可以在您的页面中订阅结果:

getFeed(rssUrl: string): Observable<RssResponse> {
  return this.http.get(...);


// In MyPage
getRssFeed() {
    this.rssProvider.getFeed(this.rssUrl).subscribe(data => {
        this.episodes = data.items;
    });
}
Run Code Online (Sandbox Code Playgroud)