2016-05-23 3 views
3

Я новичок в 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'); 
    } 

Я хочу вообще функцию «поиск» в этом классе, который принимает запрос и тип объекта и возвращает Наблюдаемый сбор конкретных тип объекта. Я застрял здесь. Как я могу работать с generics, чтобы указать общий тип возвращаемого значения функции.

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

Есть ли способ достичь этого?

ответ

3

Попробуйте использовать класс 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.

+0

как это называется? –

+0

@ParamSingh Я добавил пример того, как его называть. – toskv

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, "..."); 

И тогда компилятор может сделать вывод, что T является предоставление его с классом (/ CTOR).

0

Вы можете сделать это с перегрузкой:

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

И жалуются на кастинге типа утка терпит неудачу (но не жалуйтесь, если говорить Track и Исполнитель имеют те же свойства и функции).

var observableError: Observable<Album[]> = x.search("test", "Track"); 
Смежные вопросы