declare var $q: IQService; interface IQService { all(x: [IPromise, IPromise, IPromise]): IPromise<[T1, T2, T3]>; all(x: [IPromise, IPromise]): IPromise<[T1, T2]>; all(x: [IPromise]): IPromise<[T1]>; when(t?: T): IPromise; } interface IPromise { then(callback: (t: T) => TResult): IPromise; } // Implicit different types var a = $q.all([$q.when(), $q.when()]); // Explicit different types var b = $q.all([$q.when(), $q.when()]); // Implicit identical types var c = $q.all([$q.when(), $q.when()]);