Having the following interface for a React component:
export interface MyInterface {
name: string;
isEasy?: boolean;
isMedium?: boolean;
isHard?: boolean;
}
It must accept maximum one property of the last three (isEasy, isMedium or isHard)
For example
<MyComponent name='John' /> // correct
<MyComponent name='John' isEasy /> // correct
<MyComponent name='John' isEasy isHard /> // incorrect
How can it be done?
Tried to union them like this without success:
interface MyInterface {
name: string;
}
interface MyInterfaceEasy extends MyInterface {
isEasy: true;
isMedium?: never;
isHard?: never;
}
interface MyInterfaceMedium extends MyInterface {
isEasy: never;
isMedium?: true;
isHard?: never;
}
interface MyInterfaceHard extends MyInterface {
isEasy: never;
isMedium?: never;
isHard?: true;
}
export type ExportedInterface =
| MyInterfaceEasy
| MyInterfaceMedium
| MyInterfaceHard;
When testing it with: <MyComponent name='John' isEasy />
Error:
Types of property 'isEasy' are incompatible.
Type 'boolean' is not assignable to type 'undefined'
2
Answers
I think you can change your code to:
and it should works.
One way of doing that is to always have one of the difficulties be
true
and the rest?: false
. That way you can omit all props or all but one. Setting two difficulties will set both totrue
and therefore they won’t be assignable toExportedInterface
and Typescript will error.You can see an example of this here or in the Typescript playground:
You might also consider taking a different approach where you have one prop that is
difficulty?: 'easy' | 'medium' | 'hard'
. That would only allow one difficulty.You can see that approach here or in the Typescript playground: