Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Generics to type defaultProp arrow function methods in React

so we can across an issue where we have an interface that provides a method for creating styles. It accepts a generic and parameterizes the return type as such, see below:

export interface StyleConfig {
    rootContainer: any;
}

export default interface AcceptsStyles {
    createStyles: <C extends StyleConfig>(theme: any) => C;
}

Now in the class that is utilizing this interface, we're trying to pass the interface that we'd like C to be:

export const defaultProps: Partial<Props<any>> = {
    createStyles: function <ListItemStyleConfig>(theme: any): ListItemStyleConfig { return Styles(theme) },
};

We've managed to get this to work using a normal function definition; however, if we try it with an arrow function it gives us issues:

createStyles<ListItemStyleConfig>: (theme: any): ListItemStyleConfig => Styles(theme),

I'm not sure if we're just parameterizing this the right way or what, but we get errors like Type '<ListItemStyleConfig>() => (theme: any) => any' is not assignable to type '<C extends StyleConfig>(theme: any) => C'. Type '(theme: any) => any' is not assignable to type 'C'.

Does anyone have any idea of how we could essentially do with arrow functions what we are doing with the normal function definition, and if this is even the right way to approach it?

like image 287
ehutchllew Avatar asked Aug 06 '26 06:08

ehutchllew


1 Answers

You might not need the <ListItemStyleConfig> on your createStyles, the TS compiler is almost always able to infer the generic type from the return value of your function.

createStyles: (theme: any): ListItemStyleConfig => Styles(theme) // As long as Props extends AcceptsStyles, the function will be correctly inferred and valid

Depending on the return type of Styles, you might not even need a return type (and it can be inferred), e.g.

createStyles: (theme: any) => Styles(theme) // should infer the generic from return type of Styles

or, depending on the signature of Styles (and whether it uses an unbounded this), you could even pass it directly like so:

createStyles: Styles // equivalent to theme => Styles(theme) as long as binding is the same and Styles takes only a single parameter

The TypeScript compiler is almost always able to infer generics for you! I try to avoid explicitly declaring them unless there is some ambiguity.

like image 165
Spencer Avatar answered Aug 07 '26 22:08

Spencer



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!