我正在尝试使类实例方法中定义的用户类型保护起作用,我正在使用最新的 typescript 4.0.5,并且找不到修复它的方法。我收到错误(下面评论)。这是打字稿游乐场。
// Example with class method user type guard
class A{
constructor(public name?: string){}
public hasName(): this is {name: string}{
return name !== undefined;
}
}
const listA = [new A('John'), new A(), new A('Mark')].filter(a => a.hasName())
console.log(listA[0].name.toUpperCase()) // Error: Object is possibly undefined
// Example with function user type guard
class B{
constructor(public name?: string){}
}
const hasName = (b: B): b is {name: string} => name !== undefined;
const listB = [new B('John'), new B(), new B('Mark')].filter(hasName);
console.log(listB[0].name.toUpperCase()) // No error, type guard makes Typescript know it can not be undefined
Run Code Online (Sandbox Code Playgroud)
如您所知,当您传入用户定义的类型保护函数作为其参数时,标准 TypeScript 库中的方法的调用签名之一Array<T>.filter()将缩小返回数组元素的类型:
interface Array<T> {
filter<S extends T>(
callbackfn: (value: T, index: number, array: T[]) => value is S,
thisArg?: any
): S[];
}
Run Code Online (Sandbox Code Playgroud)
该hasName()函数是一个用户定义的类型保护,并且可以工作。
但是,当您使用 with 调用a => a.hasName()它时,该函数的类型会被推断为仅返回boolean。这是因为用户定义的类型保护函数不会传播,也不会为您推断;请参阅microsoft/TypeScript#10734。一旦您开始使用类似的类型,编译器x is Y通常会对其进行扩展。boolean
您可以使用箭头函数返回类型注释告诉编译器您的箭头函数回调也是类型保护,如下所示:
const listA = [new A('John'), new A(), new A('Mark')].filter(
(a): a is A & { name: string } => a.hasName()
);
console.log(listA[0].name.toUpperCase())
Run Code Online (Sandbox Code Playgroud)
请注意,类型谓词a is A & {name: string}不只是a is {name: string}。这是因为,严格来说,类型谓词必须缩小相关值,并且{name: string}不是A(since{name:string}缺少该hasName()方法) 的子类型。this is {name: string}显然,您可以在方法中逃脱,因为this在类型谓词中没有严格检查多态性(如microsoft/TypeScript#5906中实现的那样)。无论如何,交叉路口A & {name: string}修复了它。
| 归档时间: |
|
| 查看次数: |
1586 次 |
| 最近记录: |