I have an ambient TypeScript module represent a library that supports any Promises/A+ library:
interface Test {
funcName():Promise<string>;
}
So I need to adjust it in such a way as to make the protocol of any promise library accessible on declarative level:
interface Test<P> {
funcName():P<string>;
}
But the TypeScript immediately complains: Type 'P' is not generic
, before I even use it.
Note that I cannot include a custom promise library into the same file as Test
, because I have to pass it in from another module.
And if I change the code to this:
interface AnyPromise<T, P extends Promise<T>> {
}
interface Test<P> {
funcName():AnyPromise<string, P<string>>;
}
It also complains error TS2315: Type 'P' is not generic.
within this part: P<string>
.
In the end I need to be able to do something like this:
import * as promise from 'bluebird'; // from Bluebird ambient declarations
import {Test} from 'test';
var Test<promise> t; // plus initialize it;
t.funcName().finally(())=>{
}); // NOTE: 'finally' is to be visible from Bluebird (doesn't exist in ES6 Promise)
To clarify again, I use Bluebird just as an example, as I need a solution to support any promise library, not one specific.
This requires higher kinded types to land in TypeScript. The issue that tracks them is here:
https://github.com/Microsoft/TypeScript/issues/1213
As of April 2016, its not yet possible.
You can approximate some of it with product types, but it needs a modification of the PromiseLike
type and you will need to explicitly pass the type parameter around any time you use then
within your library:
interface HKPromiseLike<T> {
then<TResult, P>(onfulfilled?: (value: T) => TResult | PromiseLike<TResult>, onrejected?: (reason: any) => TResult | PromiseLike<TResult>): P & HKPromiseLike<TResult>;
then<TResult, P>(onfulfilled?: (value: T) => TResult | PromiseLike<TResult>, onrejected?: (reason: any) => void): P & HKPromiseLike<TResult>;
}
class Wrapper<T, P> {
constructor(public p:P & HKPromiseLike<T>) {}
map<U>(f:(t:T) => U) {
var res = this.p.then<U, P>(f)
var w = new Wrapper(res);
return w
}
}
To specialize this wrapper, you must use class/extends.
class Specialized<T> extends Wrapper<T, SomePromise<T>> { }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With