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).