typescript - 负类型断言返回谓词
问题描述
我正在尝试编写两个 jest 函数,它们期望一个对象是否是某种类型的实例。
正面的例子expectInstanceOf
就像一种魅力,但负面的例子expectNotInstanceOf
却没有。
export function expectInstanceOf<E, A extends unknown[]>(obj: unknown, type: new (...args: A) => E): asserts obj is E {
expect(obj).toBeInstanceOf(type);
}
export function expectNotInstanceOf<E, A extends unknown[]>(obj: unknown, type: new (...args: A) => E): asserts obj is Exclude<typeof obj, E> {
expect(obj).not.toBeInstanceOf(type);
}
class Foo {
foo() {
/**/
}
}
class Bar {
bar() {
/**/
}
}
function foo(obj: Foo | Bar) {
expectInstanceOf(obj, Foo);
obj.foo();
}
function notFoo(obj: Foo | Bar) {
expectNotInstanceOf(obj, Foo);
obj.bar(); // Property 'bar' does not exist on type 'Foo | Bar'.
}
我该如何解决expectNotInstanceOf
?
解决方案
在您的代码中,typeof obj
始终是unknown
类型(您不能使用类型typeof
查询运算符来“抽象”特定类型),并且实用 程序Exclude<T, U>
类型仅过滤. 不是联合,所以很可能是(我想它也可能是if is的类型)。因此,虽然缩小到, expectNotInstanceOf unknown`,但没有帮助。T
unknown
Exclude<unknown, E>
unknown
never
E
unknown
expectInstanceOf
E
narrows to
您想要做的是使其obj
拥有自己的泛型类型参数(例如T
),然后用T
. 例如:
function expectInstanceOf<T, E, A extends unknown[]>(
obj: T, type: new (...args: A) => E): asserts obj is T & E { }
function expectNotInstanceOf<T, E, A extends unknown[]>(
obj: T, type: new (...args: A) => E): asserts obj is T & Exclude<T, E> { }
现在示例代码可以按需要工作:
function foo(obj: Foo | Bar) {
expectInstanceOf(obj, Foo);
obj.foo(); // okay
}
function notFoo(obj: Foo | Bar) {
expectNotInstanceOf(obj, Foo);
obj.bar(); // okay
}
推荐阅读
- python - 如何有条件地沿numpy ndarray的特定轴在特定位置设置值
- java - 为什么 java Arrays.binarySearch 返回奇怪的结果?
- google-sheets - Google 服务帐户无法使用 gspread 编辑/更新 Google 表格
- blazor - 如何制作 matblazor RTL(从右到左)
- swift - 如何在 swiftUI 中的父视图中运行
- php - PHP 将条件附加到准备好的语句
- asp.net-core - Core 3.0 ApplicationUser 始终为空
- html - 自定义 :before 和 :after 部分的可变显示宽度
- react-native - 反应本机滚动视图未正确包装文本元素(连续显示)
- mysql - 将 AUTO_INCREMENT 主键字段更改为 NOT NULL 可防止记录插入错误“字段没有默认值”