TypeScript Add type predicate to Object.is

zbsbpyhn  于 6个月前  发布在  TypeScript
关注(0)|答案(2)|浏览(49)

搜索词

object.is
类型 predicate

建议

当a是b时,a和b必须具有相同的类型,因此我建议添加一些带有类型 predicate 的泛型重载。

interface ObjectConstructor {
  is<A, B extends A> (a: A, b: B): a is B
  is<A extends B, B> (a: A, b: B): b is A
  is (a: any, b: any): boolean
}

检查清单

我的建议满足以下准则:

  • 这不会对现有的TypeScript/JavaScript代码造成破坏性更改
  • 这不会改变现有JavaScript代码的运行时行为
  • 这可以在不根据表达式的类型生成不同的JS的情况下实现
  • 这不是一个运行时特性(例如库功能、使用JavaScript输出的非ECMAScript语法等)
  • 这个特性将与TypeScript's Design Goals的其他部分保持一致。
afdcj2ne

afdcj2ne1#

我在意识到 Object.is(a, b) 不像 a === b 那样缩小类型时遇到了这个问题。

看起来 TS 5.0 的新 const 类型参数对于类型缩小更优越:

is: (<const T, U extends T>(a: T, b: U) => a is U) &
    (<const T, U extends T>(a: U, b: T) => b is U)

查看Playground示例。

为了进行比较,原始帖子的定义没有正确处理第二种情况。
也许 TS5 是添加这个更好的 Object.is 类型的合适时机?

ktecyv1j

ktecyv1j2#

经过进一步思考,我们意识到这些定义没有妥善处理 ab 部分重叠类型的情况。

目前一个合理的启发式方法似乎是这样的:

const is: {
  <B, A extends B> (a: A, b: B): b is A,
  <A, B> (a: A, b: B): a is A & B
} = Object.is as any;
  • 如果第二个参数更一般,缩小它。
  • 否则,在所有情况下缩小第一个参数。

Playground 示例
在此之前,这似乎是我们能做的最好的事情,直到 #26916

相关问题