javascript - Is it possible to combine user defined type guards in TypeScript? - Stack Overflow

Giventype Maybe<T> = T | undefined;class Obj {jbo: Maybe<Jbo>;}, is it possible to define

Given

type Maybe<T> = T | undefined;

class Obj {
    jbo: Maybe<Jbo>;
}

, is it possible to define a function that given a o: Maybe<Obj> asserts the types of both o and o.jbo?

I'm thinking of something like:

function everythingIsDefined(o: Maybe<Obj>):o is Obj && o.jbo is Jbo {
    // checks in here
}

Given

type Maybe<T> = T | undefined;

class Obj {
    jbo: Maybe<Jbo>;
}

, is it possible to define a function that given a o: Maybe<Obj> asserts the types of both o and o.jbo?

I'm thinking of something like:

function everythingIsDefined(o: Maybe<Obj>):o is Obj && o.jbo is Jbo {
    // checks in here
}
Share Improve this question edited Jul 27, 2017 at 17:05 gen asked Jul 27, 2017 at 16:50 gengen 10k14 gold badges37 silver badges66 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 8

A user-defined typeguard can only return one x is T. Luckily, you can use unions and intersections in your choice of T. So, for example:

function everythingIsDefined(o: Maybe<Obj>): o is Obj & {jbo: Jbo} {
    return typeof o !== 'undefined' && typeof o.jbo !== 'undefined';
}

The everythingIsDefined function asserts that the input is both an Obj (as opposed to undefined), and an object whose jbo property is a Jbo (as opposed to undefined). So you can use it like this:

if (everythingIsDefined(obj)) {
  console.log(obj.jbo.toString()) // no error
} 

Yeah, you can pull that off:

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;
}

And then:

let obj: DeepMaybe<Obj> = {} as Obj;
if (everythingIsDefined(obj)) {
    // type of obj.jbo is Jbo
} else {
    // type of obj.jbo is Maybe<Jbo>
}

(code in playground)

Explanation:
There's probably no way to aplish that with the types you provided (that is Obj.jbo: Maybe<Jbo>).
Instead, the class Obj needs to define its properties as the actual type, but if you type your variable as DeepMaybe<Obj> (or anything else instead of Obj) then you get the same thing.

The difference is now, because DeepMaybe is a mapped type you have better control on how to create the type guard.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744687910a4588033.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信