Generic return type of function in Typescript
You can do it with overloads:
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;
}
}
Which will give you the correct type:
var observable = x.search("test", "Track");
And this will give a compile error on incompatible objects:
var observableError: Observable<Album[]> = x.search("test", "Track");
Try using the Array class instead of []. Also define a generic T type on the search function.
search<T>(query: string, type: string): Observable<Array<T>> {
return this.query(`/search`, [
`q=${query}`,
`type=${type}`
]);
}
You should be able to call it like this:
let result = search<Artist>('someQuery', 'artist');
You can find more about generics in typescript in the Generics chapter in the handbook here.
As @toskv answered, you can add a generics type to the method signature, but the compiler has no way of inferring the type so you'll have to add it:
myObj.search<Track>(query, "track");
However, you can do something like:
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, "...");
And then the compiler can infer what the T
is by providing it with the class (/ctor).