Jas*_*ban 6 type-safety promise typescript
d.ts各种promise库的当前定义文件似乎放弃了提供给故障回调的数据类型.
interface Deferred<T> {
notify(update: any): void;
promise: Promise<T>;
reject(reason: any): void;
resolve(value?: T): void;
resolve(value?: Promise<T>): void;
}
Run Code Online (Sandbox Code Playgroud)
interface Deferred<T> {
promise: Promise<T>;
resolve(value: T): void;
reject(reason: any): void;
notify(value: any): void;
makeNodeResolver(): (reason: any, value: T) => void;
}
Run Code Online (Sandbox Code Playgroud)
fail(failCallback1?: JQueryPromiseCallback<any>|JQueryPromiseCallback<any>[], ...failCallbacksN: Array<JQueryPromiseCallback<any>|JQueryPromiseCallback<any>[]>): JQueryPromise<T>;
Run Code Online (Sandbox Code Playgroud)
我没有看到任何承诺/ A +规格的建议,我认为reason 不能键入.
我没有尝试它qdts但类型的信息似乎迷失在从过渡'T到'U发生,我不完全理解为什么有如此-我尝试(机械增加'N和'F类型的参数<T>和'O和'G类型参数<U>并按照我认为的那样输入内容,这主要{}是因为它是新添加的类型参数的类型.
有没有理由不能给他们自己的类型参数?是否有可以完全打字的承诺结构?
哎呀,这真的很难.这实际上是你在这里提出的一个很好的问题.
让我先说一下
完全可以创建一个将异常考虑在内的承诺类型.当我用一种打字语言实现一个promise库时,我开始使用一种Promise<T,E>类型,后来又恢复了Promise<T>- 它工作但它并不好玩.你所要求的是一个名字.
你在这里实际要求的是要检查的异常 - 这是一个函数必须声明它可能抛出的异常类型 - 有些语言实际上对异常这样做了......有一种语言可以做到 - Java.在Java中,当您有一个可能抛出异常的方法(RuntimeException除外)时,它必须声明它:
public T foo() throws E {}
Run Code Online (Sandbox Code Playgroud)
请参阅,在Java中 - 返回类型和错误类型都是方法签名的一部分.这是一个有争议的选择,很多人觉得这很乏味.它在其他语言的开发者中非常不受欢迎,因为它迫使你编写了很多狡猾的代码.
假设您有一个函数返回一个promise,它使数据库连接获取URL,发出Web请求并将其写入文件.与Java相同的承诺是这样的:
Promise<T, FileAccessError | DatabaseError | WebRequestError | WebConnectionError | TypeError>
Run Code Online (Sandbox Code Playgroud)
多次输入并不是很有趣 - 因此这些语言中的异常类型(如C#)通常是隐含的.也就是说,如果你喜欢那种风格的选择,你肯定应该这样做.这不是真正的微不足道 - 承诺的类型已经相当复杂:
then<T,U> :: Promise<T> -> T -> Promise<U> | U -> Promise<U>
Run Code Online (Sandbox Code Playgroud)
这就是做什么then- 它需要T类型的承诺,以及一个回调,它接受一个T并返回一个值(U)或一个值的承诺(Promise) - 并返回一个Promise(展开和转换).实际类型甚至更难,因为那时有第二个失败参数 - 两个参数都是可选的:
then<T,U> :: Promise<T> -> (T -> Promise<U> | U) | null) -> ((Promise<T> -> any -> Promise<U> | U) | null) -> Promise<U>
Run Code Online (Sandbox Code Playgroud)
如果您添加错误处理,这将变得非常"有趣",因为所有这些步骤现在都有一个额外的错误路径:
then<T,E,U,E2> :: Promise<T,E> -> (T -> Promise<U, E2> | U) | null -> (E -> Promise<U, E2> | U) | null -> Promise<U>
Run Code Online (Sandbox Code Playgroud)
基本上 - then现在有4种类型的参数,这是人们通常想要避免的:)这完全可能,但由你决定.
我认为实现此类目标的主要挑战之一是参数是then可选的,并且其返回类型取决于它们是否是函数。Q.d.ts即使只有一个类型参数,也没有得到正确的结果:
then<U>(onFulfill?: (value: T) => U | IPromise<U>,
onReject?: (error: any) => U | IPromise<U>,
onProgress?: Function): Promise<U>;
Run Code Online (Sandbox Code Playgroud)
这表示 的返回类型Promise<T>.then()是Promise<U>,但如果onFulfill未指定,则返回类型实际上是Promise<T>!
onFulfill这甚至没有考虑到和都可以抛出的事实onReject,为您提供了五个不同的错误源来协调以确定 的类型p.then(onFulfill, onReject):
pif的拒绝值onReject未指定onFulfillonFulfillonRejectonReject我很确定甚至没有办法在 TypeScript 中表达项目符号 2 和 4,因为它没有检查异常。
如果我们用同步代码进行类比,则可以很好地定义代码块的结果值。代码块可能引发的错误很少是(除非,正如本杰明指出的,您是用 Java 编写的)。
进一步类比,即使 TypeScript 具有强类型,它甚至不提供(据我所知)在捕获的异常上指定类型的机制,因此带有any错误类型的 Promise 与 TypeScript 处理同步代码中的错误的方式是一致的。
本页关于此事的评论部分包含一条我认为与此非常相关的评论:
根据定义,异常是一种“异常”情况,并且可能由于多种原因而发生(例如语法错误、堆栈溢出等)。虽然大多数错误确实源自 Error 类型,但您调用的某些内容也可能会抛出任何错误。
同一页面上给出的不支持类型化异常的原因在这里也非常相关:
由于我们不知道函数可能会抛出什么异常,因此允许在“catch”变量上使用类型注释将具有很大的误导性——它不是异常过滤器,也不是类型安全的保证。
所以我的建议是不要尝试在类型定义中确定错误类型。异常本质上是不可预测的,并且类型化定义.then已经很难定义了。
另请注意:许多包含类似 Promise 的结构的强类型语言也没有任何作用来表达它们可能产生的潜在错误的类型。.NET 的Task<T>结果只有一个类型参数,Scala 的Future[T]. Scala 的错误封装机制Try[T](它是 接口的一部分Future[T])除了继承自 之外,不保证其结果错误类型Throwable。所以我想说 TypeScript 中的单类型参数承诺是很好的。
| 归档时间: |
|
| 查看次数: |
695 次 |
| 最近记录: |