使用自定义诺言作为通用类型 [英] Using a custom promise as a generic type

查看:53
本文介绍了使用自定义诺言作为通用类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个环境TypeScript模块,代表一个支持任何Promises/A +库的库:

I have an ambient TypeScript module represent a library that supports any Promises/A+ library:

interface Test {
  funcName():Promise<string>;
}

因此,我需要对其进行调整,以使任何promise库的协议都可以在声明级别访问:

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>;
}

但是TypeScript立即抱怨:Type 'P' is not generic,甚至没有使用它.

But the TypeScript immediately complains: Type 'P' is not generic, before I even use it.

请注意,我无法将自定义的Promise库与Test包含在同一文件中,因为我必须将其从另一个模块传递进来.

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>>;
}

它在此部分P<string>中也抱怨error TS2315: Type 'P' is not generic..

最后,我需要能够执行以下操作:

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)

再次澄清一下,我仅以Bluebird为例,因为我需要一种解决方案来支持任何Promise库,而不是一个特定的库.

To clarify again, I use Bluebird just as an example, as I need a solution to support any promise library, not one specific.

推荐答案

这需要更高种类的类型才能放入TypeScript.跟踪它们的问题在这里:

This requires higher kinded types to land in TypeScript. The issue that tracks them is here:

https://github.com/Microsoft/TypeScript/issues/1213

截至2016年4月,尚不可能.

As of April 2016, its not yet possible.

您可以使用产品类型来近似估计其中的一部分,但是需要对PromiseLike类型进行修改,并且您在库中使用then的任何时候都需要显式传递type参数:

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
    }
}

要专门使用此包装器,必须使用class/extends.

To specialize this wrapper, you must use class/extends.

class Specialized<T> extends Wrapper<T, SomePromise<T>> { }

这篇关于使用自定义诺言作为通用类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆