React Typescript区分不同的道具类型,从两种类型中选择一种



我有两个Typescript接口:

type ISecond = {
timeType: string
secondTime: number
}
type IDay = {
timeType: string
startTime: number
endTime: number
}

我的反应功能道具类型,

...
const CountDown: React.FC<Iprops> = (params: Iprops) => {
...
}
...

我怎么能让它只从这两种中选择一种呢?如果我的道具有secondTime,它就不能有道具startTimeendTime

我正在使用type Iprops = ISecond | IDay,但不能限制它只能从一个中选择。

有几种方法可以处理它。

最简单的方法

只需添加一个可共享的属性。例如: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
}
}

或者你可以走更长的路,但我相信更安全。你可以添加类型保护并保持你的类型原样:

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

游乐场

关于使用带有react组件的并集的更多信息,你可以在我的文章中找到

您需要能够区分您正在使用的不同类型的道具,这些道具可以使用in运算符来实现。由于IDay接口包含属性endTime,而ISecond不包含属性,因此您可以使用它来区分两者(您也可以在此处使用startTime(。

const CountDown: React.FC<Iprops> = (params: Iprops) => {
'endTime' in params ? (
// Logic for using IDay goes here 
) : (
// Logic for using ISecond goes here 
)
}

使用函数重载

function CountDown (params: ISecond);
function CountDown (params: IDay) {
...
}

查看文档。

最新更新