是否可以在TypeScript中结合用户定义的类型警卫?
问题描述:
鉴于是否可以在TypeScript中结合用户定义的类型警卫?
type Maybe<T> = T | undefined;
class Obj {
jbo: Maybe<Jbo>;
}
,是可以定义给定一个o: Maybe<Obj>
断言类型都o
和o.jbo
的功能?
我喜欢思考的东西:
function everythingIsDefined(o: Maybe<Obj>):o is Obj && o.jbo is Jbo {
// checks in here
}
答
用户定义的键盘锁只能返回一个x is T
。幸运的是,你可以在你选择的T
中使用联合和交叉点。因此,例如:
function everythingIsDefined(o: Maybe<Obj>): o is Obj & {jbo: Jbo} {
return typeof o !== 'undefined' && typeof o.jbo !== 'undefined';
}
的everythingIsDefined
功能断言输入是既一个Obj
(相对于未定义),和一个对象,其jbo
属性是一个Jbo
(相对于未定义)。所以,你可以使用它像这样:
if (everythingIsDefined(obj)) {
console.log(obj.jbo.toString()) // no error
}
答
呀,你可以拉其关闭:
type Maybe<T> = T | undefined;
type DeepMaybe<T> = { [K in keyof T]: Maybe<T[K]> };
class Obj {
jbo: Jbo;
}
function everythingIsDefined<T>(o: DeepMaybe<T>): o is T {
return false;
}
然后:
let obj: DeepMaybe<Obj> = {} as Obj;
if (everythingIsDefined(obj)) {
// type of obj.jbo is Jbo
} else {
// type of obj.jbo is Maybe<Jbo>
}
说明:
根据您提供的类型(即Obj.jbo: Maybe<Jbo>
),可能没有办法实现这一点。
相反,类Obj
需要将其属性定义为实际类型,但如果您将变量键入为DeepMaybe<Obj>
(或其他任何内容而不是Obj
),那么您会得到同样的结果。
现在的区别是,因为DeepMaybe
是一种映射类型,您可以更好地控制如何创建类型警卫。
很好的交点 –
这真棒,谢谢! – gen