I am trying to define a type
type myType{
....
counter?: number,
maxCount?: number,
}
with counter being required if (and only if) maxCount is provided. What are the options to specify it in typescript?
CodePudding user response:
You will need MyType
to be a union type where one member of the union requires the relevant properties, while the other member either prohibits them or makes them optional, depending on the use case.
TypeScript doesn't have an "official" or direct syntax for prohibiting a property. Merely leaving the property out of the type definition doesn't really have this effect, especially with unions. See Why does A | B allow a combination of both, and how can I prevent it? for more information.
Instead, you can make the property optional with a value of the impossible never
type. Since you cannot find a value of the never
type, an optional property of type never
can only meaningfully be satisfied by not including the property at all.
I'd recommend making a base type that your union members extend.
interface BaseMyType {
someProp: string;
counter?: number;
maxCount?: number;
}
If you want to allow either both maxCount
and counter
or neither of them to appear, then you can do it like this:
interface MyTypeWithCounter extends BaseMyType {
counter: number,
maxCount: number
}
interface MyTypeWithoutCounter extends BaseMyType {
counter?: never,
maxCount?: never;
}
type MyType = MyTypeWithCounter | MyTypeWithoutCounter
And test it:
let myType: MyType;
myType = { someProp: "abc", counter: 123, maxCount: 456 }; // okay
myType = { someProp: "abc", maxCount: 456 }; // error
myType = { someProp: "abc", counter: 123, }; // error
myType = { someProp: "abc", }; // okay
On the other hand, if you just want to make sure that counter
appears if maxCount
does, and otherwise counter
should be allowed but not required, then you can write it this way:
interface MyTypeWithMaxCount extends BaseMyType {
counter: number,
maxCount: number
}
interface MyTypeWithoutMaxCount extends BaseMyType {
maxCount?: never;
}
type MyType = MyTypeWithMaxCount | MyTypeWithoutMaxCount
And test it:
let myType: MyType;
myType = { someProp: "abc", counter: 123, maxCount: 456 }; // okay
myType = { someProp: "abc", maxCount: 456 }; // error
myType = { someProp: "abc", counter: 123, }; // okay
myType = { someProp: "abc", }; // okay