I have a type that looks like something as follows:
type MyType = {
a: string;
b: string;
c?: number;
d?: string;
}
There are objects of this type which can look like:
const myObj1: MyType = { a, b };
const myObj2: MyType = { a, b, c, d };
So if an object of MyType
has the property c
, it will definitely have property d
. Is there a way to define this type as such that I do not have to non-null assert or check for both types other than extending the type into a different type?
CodePudding user response:
If you're allowed to change MyType
, one approach is to separate the c
and d
properties into a different object where they're required, and alternate with an intersection with that object.
type AB = {
a: string;
b: string;
};
type MyType = AB | AB & {
c: number;
d: string;
}
This way, if something of MyType is seen to have a c
property, TypeScript will see that it definitely also has a d
property.
CodePudding user response:
If you want property 'd' to exist only when 'c' is defined and vice-versa, it would be worth using extended
interfaces and overwriting the optional properties as never
as follows:
type Base = {
a: string;
b: string;
c?: number;
d?: string;
}
interface Concrete1 extends Base {
c?: never;
d?: never;
}
interface Concrete2 extends Base {
c: number;
d: string;
}
type MyType = Concrete1 | Concrete2;
const myObj1: MyType = { a: 'a', b: 'b' };