3

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?

0

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

1 Comment

We create an object literal in our styles.ts file that is typed to ListItemStyleConfig, and works properly. We then export a StyleSheet.create() using that object with type of any, and import it as Styles(), and that's the only way we get it to not complain in the defaultProps. So we were just curious if there was a way to parameterize the defaultProps to specifically accept a structure of ListItemStyleConfig. When we instantiate it like const styles: ListItemStyleConfig = Styles(theme) that works, so I'm not sure if we NEED to parameterize the defaultProp.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.