#No error - why?

20 messages · Page 1 of 1 (latest)

rustic archBOT
#
onkeltem#0

Preview:```ts
import React, {FC} from "react"

type Props<TExtraProps> = {foo: string} & TExtraProps

declare function withFoo<TExtraProps>(
Component: FC<Props<TExtraProps>>
): TExtraProps

// Demo A

declare const CompA: FC<{a: string}>

const CompAAug = withFoo(CompA)
...```

limpid heart
#

I don't understand why there's no error in the line: const CompAAug = withFoo(CompA);

#

withFoo should take a component with {foo: string}

#

apart from some extra properties it may have

#

Don't pay attention to the meaning of the rest - it's meaningless

clear coyote
#

It gets clearer if you get rid of FC to show the function types

type Props<TExtraProps> = { foo: string } & TExtraProps;
declare function withFoo<TExtraProps>(Component: (x: Props<TExtraProps>) => void): TExtraProps

declare const CompA: (props: { a: string }) => void
const CompAAug = withFoo(CompA);
#

Then this can be seen as a case of

#

!:variance

rustic archBOT
#
tjjfvi#0
`!t6:variance`:

Here's the example with Dog and Animal, explaining co/contra/in variance:

  • Covariance: () => Dog is assignable to () => Animal, because Dog is assignable to Animal; it "preserves the direction of the assignability"
  • Contravariance: (Animal) => void is assignable to (Dog) => void, because something that expects an Animal can also take a Dog; it "reverses the direction of the assignability"
  • Invariance: (Animal) => Animal is not assignable to (Dog) => Dog, because not all returned Animals are Dogs, and (Dog) => Dog is not assignable to (Animal) => Animal, because something expecting a Dog cannot take any other kind of Animal
clear coyote
#

Specifically, contravariance here

limpid heart
#

Thanks @clear coyote
Need some time to get it... Because it's counter-intuitive

#

And I don't really get it yet

#

Then logical question: how to put this constraint then?

#

If I really need to accept a component with specific prop

#

More minimal example:

rustic archBOT
#
onkeltem#0

Preview:ts declare function withFoo( Component: (x: {foo: string}) => void ): unknown declare const CompA: () => void withFoo(CompA)

clear coyote
#

You almost certainly don't actually want to do that... you'd have to use a validating generic, which is generally not great for intellisense. It's the same kind of thing where Array#map takes three parameters, but you don't have to specify all of them

limpid heart
#

hm, interesting 🙂 I agree that would be silly

#

to demand them

#

And I agree that it's not even my case.