I have a component that has 2 properties. It may or may not accept one of those (say prop b), but you always need to pass the prop a. If the b prop is passed, it should change the typings of a.
interface FirstCase<T> {
a: (param: CBParam<T>) => Element
b: OtherInterface<T>
}
interface SecondCase {
a: () => Element
b?: undefined
}
type ComponentProps<T> = FirstCase<T> | SecondCase
So, in my component im checking if the b prop is defined, and hoping that typescript infer the correct typings of a
function MyComponent<T>({a, b}: ComponentProps<T>): Element {
return b ? a('some param') : a()
}
The thing is that in the IDE there is no error as I was expecting, but if I run npx tsc
on the console, it complains that I need to pass a param to a (error TS2554: Expected 1 arguments, but got 0.
)
CodePudding user response:
I believe you need a type guard function: https://www.typescriptlang.org/docs/handbook/advanced-types.html
Maybe specific example they use will help you:
function isFish(pet: Fish | Bird): pet is Fish { return (pet as Fish).swim !== undefined; }
CodePudding user response:
I ended up doing type casting
return b ? a('some param') : (a as SecondCase['a'])()
CodePudding user response:
Destructuring a
and b
does not help the compiler here. If you instead keep it as props
and then test b
, it "knows" that a
is related.
This does work without casting or compiler errors.
interface CBParam<T> {}
interface OtherInterface<T> {}
interface FirstCase<T> {
a: (param: CBParam<T>) => Element
b: OtherInterface<T>
}
interface SecondCase {
a: () => Element
b?: undefined
}
type ComponentProps<T> = FirstCase<T> | SecondCase
function MyComponent<T>(props: ComponentProps<T>): Element {
return props.b ? props.a('some param') : props.a()
}