Reputation: 890
I have two Typescript interfaces:
type ISecond = {
timeType: string
secondTime: number
}
type IDay = {
timeType: string
startTime: number
endTime: number
}
With my react function props types,
...
const CountDown: React.FC<Iprops> = (params: Iprops) => {
...
}
...
How can I make it only choose from one of these two? If my props has secondTime
, it cannot have props startTime
and endTime
.
I'm using type Iprops = ISecond | IDay
, but cannot limit it only choose from one.
Upvotes: 1
Views: 937
Reputation: 33101
There are several ways to handle it.
The simplest way
Just add one sharable property. For example: type
type ISecond = {
type: 'second',
timeType: string
secondTime: number
}
type IDay = {
type: 'day',
timeType: string
startTime: number
endTime: number
}
type IProps = ISecond | IDay;
const Foo = (prop: IProps) => {
if (prop.type === 'day') {
const x = prop; // IDay
}
if (prop.type === 'second') {
const x = prop; // ISecond
}
}
Or you can go by a bit longer way, but I believe more safer. You can add typeguards and leave your types as is:
type Base = {
timeType: string
}
type ISecond = Base & {
secondTime: number
}
type IDay = Base & {
startTime: number
endTime: number
}
type IProps = ISecond | IDay;
const hasProperty = <T extends object>(obj: T, prop: string) =>
Object.hasOwnProperty.call(obj, prop);
const isSecond = (obj: IProps):obj is ISecond => hasProperty(obj, 'secondTime')
const Foo = (prop: IProps) => {
if (isSecond(prop)) {
const x = prop; // ISecond
} else {
const x = prop; // IDay
}
}
More information about using union with react components you can find in my article here
Upvotes: 2
Reputation: 2050
Use function overloading
function CountDown (params: ISecond);
function CountDown (params: IDay) {
...
}
Check the documentation.
Upvotes: 0
Reputation: 6829
You need to be able to distinguish the different types of props that you are using which can be achieved using the in
operator. As the IDay
interface contains the property endTime
and ISecond
does not you can use it to differentiate the two(you can also use startTime
here as well).
const CountDown: React.FC<Iprops> = (params: Iprops) => {
'endTime' in params ? (
// Logic for using IDay goes here
) : (
// Logic for using ISecond goes here
)
}
Upvotes: 0