I have these types (Playground):
type A = {
onChange: (e: Event) => void
}
type Props = { value: string }
type B = A & {
onChange: (props: Props) => void
}
While I can define them, I can't use them:
const b: B = {
onChange: ((props: Props) => console.log(props.value)) // error
}
I get this error:
Type '(props: Props) => void' is not assignable to type '((e: Event) => void) & ((props: Props) => void)'.
Type '(props: Props) => void' is not assignable to type '(e: Event) => void'.
Types of parameters 'props' and 'e' are incompatible.
Property 'value' is missing in type 'Event' but required in type 'Props'.(2322)
Is it possible to use the types as described and get rid of this error?
One idea that came to my mind is to use:
type B = Omit<A, 'onChange'> & {
onChange: (props: Props) => void
}
But it feels a bit odd, because it is not refactoring safe.
CodePudding user response:
Use Override
utility type-
type Override<T1, T2> = Omit<T1, keyof T2> & T2;
Override
creates a new type (say T3
) by omitting all the keys from T1
which are also in T2
(that is, the common keys). Then it creates an intersection type from T3
and T2
The whole solution would be-
type Override<T1, T2> = Omit<T1, keyof T2> & T2;
type A = {
propA: string
onChange: (e: Event) => void
}
type Props = { value: string }
type B = Override<A, {
propB: number
onChange: (props: Props) => void
}>
const b: B = {
onChange: ((props: Props) => console.log(props)),
propA: 'propA',
propB: 3
}
Ref- https://dev.to/vborodulin/ts-how-to-override-properties-with-type-intersection-554l