【问题标题】:Generic return type of function in TypescriptTypescript中函数的通用返回类型
【发布时间】:2016-05-23 08:35:33
【问题描述】:

我是 ts 新手,但我对 Java 中的泛型概念了解了一些。查询是我有三个函数:searchTrack、searchAlbum、searchArtist

  searchTrack(query: string): Observable<Track[]> {
    return this.search(query, 'track');
  }

  searchArtist(query: string): Observable<Artist[]> {
    return this.search(query, 'artist');
  }

  searchAlbum(query: string): Observable<Album[]> {
    return this.search(query, 'album');
  }

我想要这个类中的通用函数“搜索”,它接受查询和实体类型,并返回特定实体类型的集合的 Observable。我被困在这里。如何使用泛型来指定函数的泛型返回类型。

search(query: string, type: string): Observable<Array<T>> {
 return this.query(`/search`, [
   `q=${query}`,
   `type=${type}`
 ]);
}

有什么方法可以实现吗?

【问题讨论】:

    标签: function generics typescript


    【解决方案1】:

    尝试使用 Array 类而不是 []。 还要在搜索函数上定义一个通用的 T 类型。

    search<T>(query: string, type: string): Observable<Array<T>> {
     return this.query(`/search`, [
       `q=${query}`,
       `type=${type}`
     ]);
    }
    

    你应该可以这样称呼它:

    let result = search<Artist>('someQuery', 'artist');
    

    您可以在手册 here 的泛型章节中找到有关 typescript 中泛型的更多信息。

    【讨论】:

    • @ParamSingh 我添加了一个关于如何调用它的示例。
    【解决方案2】:

    正如@toskv 回答的那样,您可以将泛型类型添加到方法签名中,但编译器无法推断类型,因此您必须添加它:

    myObj.search<Track>(query, "track");
    

    但是,您可以执行以下操作:

    interface MyObservableClass {}
    
    interface MyObservableClassCtor<T extends MyObservableClass> {
        new (): T;
        getType(): string;
    }
    
    class Artist implements MyObservableClass {
        static getType(): string {
            return "artist";
        }
    }
    
    class Album implements MyObservableClass {
        static getType(): string {
            return "album";
        }
    }
    
    class Track implements MyObservableClass {
        static getType(): string {
            return "track";
        }
    }
    
    class Searcher {
        search<T extends MyObservableClass>(ctor: MyObservableClassCtor<T>, query: string): Observable<T[]> {
            return this.query(`/search`, [
                `q=${query}`,
                `type=${ ctor.getType() }`
            ]);
        }
    }
    
    let searcher: Searcher = ...;
    
    searcher.search(Track, "...");
    

    然后编译器可以通过提供类 (/ctor) 来推断 T 是什么。

    【讨论】:

      【解决方案3】:

      你可以用重载来做到这一点:

      class A {
          search<T>(query: string, type: "Track"): Observable<Track[]>;
          search<T>(query: string, type: "Artist"): Observable<Artist[]>;
          search<T>(query: string, type: "Album"): Observable<Album[]>;
          search<T>(query: string, type: string): Observable<T[]>;
          search<T>(query: string, type: string): Observable<T[]> {
              return null;
          }
      }
      

      哪个会给你正确的类型:

      var observable = x.search("test", "Track");
      

      这会在不兼容的对象上产生编译错误:

      var observableError: Observable<Album[]> = x.search("test", "Track");
      

      【讨论】:

        猜你喜欢
        • 2020-01-07
        • 2019-02-10
        • 2022-01-07
        • 1970-01-01
        • 2021-10-06
        • 2020-04-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多