如何在Typescript中声明泛型承诺,以便在泛型类型为“时”&书信电报;无效>&引用;,其中一种方法赢得了';不接受参数?
在Typescript中,我希望能够以这样一种方式定义承诺的类型,以便我可以这样做:如何在Typescript中声明泛型承诺,以便在泛型类型为“时”&书信电报;无效>&引用;,其中一种方法赢得了';不接受参数?,typescript,definitelytyped,Typescript,Definitelytyped,在Typescript中,我希望能够以这样一种方式定义承诺的类型,以便我可以这样做: //This works today: new Promise<number>((resolve)=>{ //Cool resolve(5); //Error, because I didn't pass a number: resolve(); } //This is what I want to do also: new Promise<void>((
//This works today:
new Promise<number>((resolve)=>{
//Cool
resolve(5);
//Error, because I didn't pass a number:
resolve();
}
//This is what I want to do also:
new Promise<void>((resolve)=>{
//Error, because I passed a value:
resolve(5);
//Cool, because I declared the promise to be of type void, so resolve doesn't take a value:
resolve();
}
//这在今天起作用:
新承诺((决议)=>{
//酷
决心(5);
//错误,因为我没有传递号码:
解决();
}
//这也是我想做的:
新承诺((决议)=>{
//错误,因为我传递了一个值:
决心(5);
//很酷,因为我声明promise为void类型,所以resolve不接受值:
解决();
}
我看到的承诺定义文件都声明承诺的“resolve”方法必须采用一个值。这是来自奇妙的DefiniteTypted项目的最新示例:
declare class Promise<R> implements Thenable<R> {
constructor(callback: (resolve : (result: R) => void, reject: (error: any) => void) => void);
///...
}
declare类承诺实现了该表{
构造函数(回调:(解析:(结果:R)=>void,拒绝:(错误:any)=>void)=>void);
///...
}
```
这基本上是说,“resolve回调必须传递一个类型为R的值。”对于像new promise
这样的承诺来说,这很好。Typescript将验证我们使用类型为number
的值调用resolve
但是,如果我想要一个没有值的承诺,那么我希望能够在不传递值的情况下调用resolve(),我可以这样声明我的承诺:newpromise
但我仍然被迫调用resolve并传入某种类型的值。我可以调用resolve(未定义)
,但这读起来有点奇怪
似乎无法在Typescript中正确捕获此概念:“如果此泛型具有“void”类型,则不要期望此函数具有参数。”
我能做的最接近的事情是在resolve方法中将结果标记为可选的,但这意味着结果始终是可选的,即使对于承诺的类型版本也是如此。从您希望使用承诺接口的方式来看,您似乎有时希望传递值,有时不希望传递值,所以这就是可选参数R是给你的。 如果解决带有“未定义”结果的承诺是不可接受的(在我看来,这不是一个坏主意,这可以很好地说明代码中发生了什么-承诺的结果是被定义的),我可以提出一个解决方案,这似乎正是您想要的: 我会为承诺定义一个“合同”,比如:
export interface IMyPromiseResult {
result: number;
}
并承诺使用它:
new Promise<IMyPromiseResult>((resolve)=>{
resolve(<IMyPromiseResult>{ result: 5 });
resolve(<IMyPromiseResult>{ });
}
因此,有一个可选结果是允许的,您应该对此很满意。我可能刚刚想出了一个我很满意的解决方法。如果我希望有一个承诺
来确保resolve
回调不带参数,而不是让resolve方法总是带一个可选参数,I c可以这样定义一个新类:
export class VoidPromise extends RSVP.Promise<void>{
//Note that resolve does not take a parameter here:
constructor(callback:(resolve:() => void, reject:(error:any) => void) => void){
super(callback);
}
}
导出类VoidPromise扩展了RSVP.Promise{
//请注意,“解析”在此处不接受参数:
构造函数(回调:(解析:()=>void,拒绝:(错误:any)=>void)=>void){
超级(回调);
}
}
在这种情况下,我可以这样使用它:
public static testVoidPromise() : VoidPromise{
return new VoidPromise((resolve, reject)=>{
setTimeout(1000, ()=>{
if (Math.random() < 0.5){
//Note that resolve() does NOT take a parameter
resolve();
}else{
reject(new Error("Something went wrong"));
}
})
});
}
公共静态testVoidPromise():VoidPromise{
返回新的作废承诺((解决、拒绝)=>{
设置超时(1000,()=>{
if(Math.random()<0.5){
//请注意,resolve()不接受参数
解决();
}否则{
拒绝(新错误(“出错”);
}
})
});
}
诚然,开发人员将不得不使用VoidPromise而不是简单的“Promise”,但是在不必将resolve参数错误地标记为可选参数的情况下实现了预期效果
对于我的场景,上面的代码比将所有resolve
方法标记为具有可选结果更符合我的期望。在99%的情况下,将所有结果标记为可选会感到危险。如果它总是可选的,我可以声明一个Promise
,调用resolve()
没有结果,并为我的承诺获得一个未定义的结果。在这种情况下,我应该拒绝承诺。我不相信resolve方法的参数真的是可选的。(来源:)这确实有效!
用户需要支持这样一个用例
Runnable示例太长,无法发布。但只需将最新定义和承诺代码复制/粘贴到编辑器中,您就会看到您的示例现在起作用了。感谢您花时间回答Slawek。是的,这听起来似乎是可选的。我真的更喜欢这样一种结构:,“此变量是可选的,但仅适用于具有X类型的承诺”,但我认为可选非常简单,并且接近我的意图。您提供的链接现在已断开。
public static testVoidPromise() : VoidPromise{
return new VoidPromise((resolve, reject)=>{
setTimeout(1000, ()=>{
if (Math.random() < 0.5){
//Note that resolve() does NOT take a parameter
resolve();
}else{
reject(new Error("Something went wrong"));
}
})
});
}