返回 Promise 的 TypeScript 类型函数

6
我正在开发一个Ionic应用程序,从iTunes获取RSS订阅。我已经成功获取了RSS订阅,并在我的应用程序上显示了条目。
我遇到了以下错误,并希望了解如何正确设置变量。
export class MyPage {
    episodes: any;

    ...


    getRssFeed() {
        this.rssProvider.getFeed(this.rssUrl)
            .then(data => {
                console.log(data);
                this.episodes = data.items;
        });
    }
}

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);
    }
}

如果有必要,我会使用WebStorm作为我的集成开发环境。

这是我得到的错误信息:

Typescript Error:
Property 'items' does not exist on type '{}'.

好的,items 变量被返回了,所以ionic不知道它是什么。是否有一种正确的方式来声明变量,使我不会得到红色的错误提示?

感谢您的任何建议!


rssProvider.getFeed 做什么? - Explosion Pills
嗨,Explosion Pills - 我更新了我的问题,现在已经包含了。 - Damon
2个回答

8

Promise类型

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

type ResultType = {
  items: string[]
}

接着,告诉TypeScript函数getFeed返回的是一个ResultType类型的Promise:

getFeed(rssUrl: string): Promise<ResultType>

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

return new Promise<ResultType>(resolve => {})

错误处理

最后,不要直接在getFeed中处理错误,而是使用Promise的reject来直接在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)
      }
    )
  })
}

使用方法

使用 Promise

getFeed()
  .then(feed => {
    console.log(feed)
  })
  .catch(error => {
    console.error(error)
  })

Using async/await:

try {
  const feed = await getFeed()
  console.log(feed)
} catch (error) {
  console.error(error)
}

4
当你执行return Promise时,默认的返回类型为{},因此TypeScript会认为data实际上是{}Promise接受一个泛型参数,这个参数是从.then中获取的类型,所以你可以做像Promise<{ items: any }>这样的事情。你也可以创建interface RssResponse { items: any },并且可能对项目使用比只使用any更好的类型。
return new Promise<RssResponse>(resolve => {

然而,你根本不需要将这段代码包装在 Promise 构造函数中。Observables 有一个 toPromise 方法,因此你可以简化为:

getFeed(rssUrl: string) {
    return this.http.get(...).toPromise();

...应该具有相同的功能。

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

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


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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接