有一个检查http请求类型的守卫。它作为一个库工作,并作为来自另一个库的嵌套代码停止。
export function isTenantRequest(object: unknown): object is TenantRequest {
return (
!!object && // #a Check that it is not undefined nor null. -> not null
object instanceof Object && // #b So it can contain properties. -> Object
'tenant' in object && // #c The property exists that I am going to check -> { tenant: any } !!! maybe never
object.tenant instanceof TenantDO && // #d Checks the instance -> -> { tenant: any }
validateSync(object.tenant).length === 0 // #f Validates by a validator.
);
}
在第#d行,我收到一个 typescript 错误。
error TS2339: Property 'tenant' does not exist on type 'never'.
23(#f) validateSync(object.tenant).length === 0
我猜in
操作符不能在简单的Object
上工作,因为它不能有额外的属性,这就是为什么它返回never type,并且在下一行失败。我已经改变了下一个可行的变体,但我不喜欢,因为as
操作符。
export function isTenantRequest(object: unknown): object is TenantRequest {
return (
(object as TenantRequest).tenant instanceof TenantDO &&
validateSync((object as TenantRequest).tenant).length === 0
);
}
有人建议
typeof x === 'object'
但这并没有帮助。
请给我一些建议,让它变得更好。
1条答案
按热度按时间50few1ms1#
Typescript4.3在使用
in
操作符进行缩小方面不够智能,这在Typescript4.9中得到了改变所以我认为在没有
as
类型Assert的4.3版本中这是不可能的,但是你至少可以通过聪明地选择在哪里做Assert来避免任何运行时崩溃。我可能会这样重构:
现在为了得到
value as Record<string, unknown>
行,value
* 必须 * 是一个能够拥有属性的对象。所以你Assert它是Record<string, unknown>
,它允许你访问任何属性,但不保证你从该属性中得到什么。然后,现有代码的其余部分按原样工作,以验证该属性。
参见Typescript v4.3.5 Playground
如果你想删除那个
as
,那么你很可能需要升级到一个更新的Typescript版本。