Incorrect TS definition for useRestyle hook
antoinebugni opened this issue · comments
After installing the library via yarn install
the typescript definition for useRestyle
looks like this:
import { StyleProp } from 'react-native';
import { BaseTheme, RestyleFunctionContainer, RNStyle } from '../types';
declare const useRestyle: <Theme extends BaseTheme, TRestyleProps extends Record<string, any>, TProps extends TRestyleProps & {
style?: StyleProp<RNStyle>;
}>(restyleFunctions: (RestyleFunctionContainer<TProps, Theme, keyof TProps, keyof Theme | undefined> | RestyleFunctionContainer<TProps, Theme, keyof TProps, keyof Theme | undefined>[])[], props: TProps) => Pick<TProps, Exclude<keyof TProps, keyof TProps>>;
export default useRestyle;
The return type Pick<TProps, Exclude<keyof TProps, keyof TProps>>
seems incorrect as this always results in:
<Pick<TProps, never>>
(which is the equivalent of {}
)
I imagine the intended behaviour is closer to something like:
Pick<TProps, Exclude<keyof TProps, keyof TRestyleProps>>
Apologies if I'm missing anything obvious 🙏
I am not sure if this is related, but I get a TS2345 error when I use the useRestyle
hook. So maybe this is caused by this faulty return type.
import { layout, spacing, useRestyle } from '@shopify/restyle';
import React from 'react';
const restyleFunctions = [layout, spacing];
const Button: React.FC<Props> = (props) => {
const { ...rest } = props;
const themeProps = useRestyle(restyleFunctions, rest);
^^^^^^^^^^^^^^^^
TS2345: see the (absolutely not helpful) error message in the screenshot below
};
I am not sure if this is related, but I get a TS2345 error when I use the
useRestyle
hook. So maybe this is caused by this faulty return type.import { layout, spacing, useRestyle } from '@shopify/restyle'; import React from 'react'; const restyleFunctions = [layout, spacing]; const Button: React.FC<Props> = (props) => { const { ...rest } = props; const themeProps = useRestyle(restyleFunctions, rest); ^^^^^^^^^^^^^^^^ TS2345: see the (absolutely not helpful) error message in the screenshot below };![]()
@Spielboerg I don't think that's related, I think this might be a problem with the definition of the Props
type in your example - but the definition is missing so I can't say for sure.
@antoinebugni Yes, you are right. "rest" was not typed correctly. Thank you.
Alter upgrade to version 2 i'm experiencing the same problem.
const buttonStyleFunctions = composeRestyleFunctions([
spacing,
border,
backgroundColor,
]);
const titleStyleFunctions = composeRestyleFunctions([typography]);
type RNEButtonPropsExcluded = Exclude<RNEButtonProps, "buttonStyle">;
type Props = RNEButtonPropsExcluded & {
buttonStyle?: SpacingProps<Theme> &
BorderProps<Theme> &
BackgroundColorProps<Theme>;
titleStyle?: TypographyProps<Theme>;
color?: keyof Theme["colors"];
};
export const Button = ({ buttonStyle, titleStyle, color, ...rest }: Props) => {
const theme = useTheme<Theme>();
const reStyledButton = useRestyle(buttonStyleFunctions, buttonStyle || {});
const reStyledButtonStyles = reStyledButton.style as StyleProp<ViewStyle>;
const reStyledTitle = useRestyle(titleStyleFunctions, titleStyle || {});
// @ts-ignore
const { style, ...textProps } = reStyledTitle as StyleProp<ViewStyle>;
return (
<RNEButton
{...rest}
buttonStyle={reStyledButtonStyles}
titleStyle={[
...style,
{
...textProps,
color: color ? theme.colors[color] : undefined,
},
]}
/>
);
};
I have the same problem as @bearkfear:
import {
composeRestyleFunctions,
spacing,
SpacingProps,
useRestyle
} from "@shopify/restyle";
import * as React from "react";
import { Pressable, StyleSheet } from "react-native";
import { Theme } from "../theme";
import Box from "./box";
import Text from "./text";
const restyleFunctions = composeRestyleFunctions([spacing]);
const styles = StyleSheet.create({
pressable: {
borderRadius: 8
}
});
type Props = SpacingProps<Theme> & { text: string; onPress: () => void };
function Button({ text, onPress, ...rest }: Props) {
const props = useRestyle(restyleFunctions, rest);
return (
<Box flex={1} {...props}>
<Pressable style={styles.pressable} onPress={onPress}>
<Box
flex={1}
height={44}
paddingHorizontal="m"
alignItems="center"
justifyContent="center"
backgroundColor="buttonBackground"
borderRadius={8}>
<Text variant="button">{text}</Text>
</Box>
</Pressable>
</Box>
);
}
export default Button;
The error is:
Argument of type '{ buildStyle: (props: Record<string, any>, { theme, dimensions, }: { theme: BaseTheme; dimensions: Dimensions; }) => RNStyle; properties: string[]; propertiesMap: Record<...>; }' is not assignable to parameter of type '{ buildStyle: <TInputProps extends { margin?: ResponsiveValue<"m" | "s" | "l" | "xl", { colors: { mainBackground1: string; mainBackground2: string; tabBarBackground: string; tabBarInactiveForeground: string; tabBarActiveForeground: string; ... 6 more ...; buttonBackground: string; }; spacing: { ...; }; breakpoints: ...'.
Types of property 'properties' are incompatible.
Type 'string[]' is not assignable to type '("margin" | "marginBottom" | "marginEnd" | "marginHorizontal" | "marginLeft" | "marginRight" | "marginStart" | "marginTop" | "marginVertical" | "padding" | "paddingBottom" | ... 6 more ... | "paddingVertical")[]'.
Type 'string' is not assignable to type '"margin" | "marginBottom" | "marginEnd" | "marginHorizontal" | "marginLeft" | "marginRight" | "marginStart" | "marginTop" | "marginVertical" | "padding" | "paddingBottom" | ... 6 more ... | "paddingVertical"'.ts(2345)
@bearkfear and @JuanjoFR - I don't think either of the TS errors you're experiencing here are related to this issue.
@bearkfear I can't be 100% sure for you because you've not shared the actual error
@JuanjoFR your error is related to some issue with the definition of restyleFunctions
To give you an example to illustrate the issue I raised, take the following code:
import React from 'react';
import { Image, ImageProps } from 'react-native';
import { Theme } from '@sf/styles';
export const restyleFunctions = [backgroundColor];
/** Image component */
export type MyComponentProps = ImageProps & AllProps<Theme>;
export const MyComponent: React.FC<MyComponentProps> = props => {
const restyleProps = useRestyle(restyleFunctions, props);
return <Image {...restyleProps} />;
};
☝️ this results in the following error 👇 :
No overload matches this call.
Overload 1 of 2, '(props: ImageProps | Readonly<ImageProps>): Image', gave the following error.
Property 'source' is missing in type '{}' but required in type 'Readonly<ImageProps>'.
Overload 2 of 2, '(props: ImageProps, context: any): Image', gave the following error.
Property 'source' is missing in type '{}' but required in type 'Readonly<ImageProps>'.ts(2769)
The definition of props
returned by useRestyle
is {}
- which may cause issue depending on the component. In this example, the source
prop is mandatory but missing in the TS definition for the value returned by useRestyle
.
I hope that's a bit clearer for everyone, sorry if this was confusing at all.
Hello @sbalay ! same problem here, I have a incorrect type definition with useRestyle =>
here an example https://snack.expo.dev/@ludwig-pro/expo-typescript-restyle
there are two components :
- RestyleButton.tsx (a copy / paste of the README )
- RestyleBox.tsx - a custom box to handle opacity props
@antoinebugni I believe that the issue you reported here could be solved by upgrading to the latest version of restyle (and following the migration guide)
@ludwig-vaan your issue seems a regression introduced by https://github.com/Shopify/restyle/pull/138/files, we'll try to find a solution or revert that PR. Could you create a new issue?
@sbalay I did upgrade our repo to the latest version recently and forgot to check - indeed you're right, the issue is resolved :) Thanks for pointer!
@ludwig-vaan your issue seems a regression introduced by https://github.com/Shopify/restyle/pull/138/files, we'll try to find a solution or revert that PR. Could you create a new issue?
For posterity, @ludwig-vaan did open an issue here: #159
I'm facing the same issue with @ludwig-vaan , the newest version 2.3.0 didn't resolve it yet. any suggestions?