Shopify / restyle

A type-enforced system for building UI components in React Native with TypeScript.

Home Page:https://shopify.github.io/restyle/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

TS error when attempting to create multiple variants with different keys in the theme object

tarikfp opened this issue · comments

commented

Current behavior

Is it possible to create independent variants, such as a button and a card, in the theme object without having to use the same keys for each variant? For example, having variants for a button such as smallButton and largeElevatedButton, and variants for a card such as elevatedCard, with each variant having its unique keys.

Given the following base example that is taken from docs, it throws TS error when I try to use smallBtn key in buttonVariants object. However, when I replace with smallBtn with elevated the error is gone. How can I achieve using different keys in different variants ?

import {
  createRestyleComponent,
  createTheme,
  createVariant,
  VariantProps,
} from "@shopify/restyle";

const theme = createTheme({
  // ...
  spacing: {
    s: 8,
    m: 16,
    l: 24,
  },
  colors: {
    btnTextColor: "#123123",
  },
  breakpoints: {
    phone: 0,
    tablet: 768,
  },
  // Custom button variants
  buttonVariants: {
    defaults: {},
    regular: {
      backgroundColor: "gold",
    },
    // If I try to add different key (for ex: 'smallBtn'), it will throw error in createRestyleComponent
    // However If I change smallBtn to elevated, the TS error will be gone.
    smallBtn: {},
  },
  // Card variants that is taken from docs
  cardVariants: {
    defaults: {},
    regular: {
      padding: {
        phone: "s",
        tablet: "m",
      },
    },
    elevated: {
      padding: {
        phone: "s",
        tablet: "m",
      },
      shadowColor: "#000",
      shadowOpacity: 0.2,
      shadowOffset: { width: 0, height: 5 },
      shadowRadius: 15,
      elevation: 5,
    },
  },
});

type Theme = typeof theme;

const variant = createVariant<Theme>({
  themeKey: "cardVariants",
});

const Card = createRestyleComponent<VariantProps<Theme, "cardVariants">, Theme>(
  [variant],
  // TS ERROR: Type '"elevated"' is not assignable to type 'ResponsiveValue<"regular", { phone: number; tablet: number; }> | undefined'.ts(2322)
);

const CardComponent = () => {
  <Card variant="elevated" />;
};

Expected behavior

There should not be any TS error when declaring independent variants with different keys.

To Reproduce

Complete TS error log:

Type 'RestyleFunctionContainer<VariantProps<{ spacing: { s: number; m: number; l: number; }; colors: { btnTextColor: string; }; breakpoints: { phone: number; tablet: number; }; buttonVariants: { defaults: {}; regular: { backgroundColor: string; }; smallBtn: { ...; }; }; cardVariants: { ...; }; }, "buttonVariants" | "cardV...' is not assignable to type 'RestyleFunctionContainer<VariantProps<{ spacing: { s: number; m: number; l: number; }; colors: { btnTextColor: string; }; breakpoints: { phone: number; tablet: number; }; buttonVariants: { defaults: {}; regular: { backgroundColor: string; }; smallBtn: { ...; }; }; cardVariants: { ...; }; }, "cardVariants", "variant"...'.
  Type 'RestyleFunctionContainer<VariantProps<{ spacing: { s: number; m: number; l: number; }; colors: { btnTextColor: string; }; breakpoints: { phone: number; tablet: number; }; buttonVariants: { defaults: {}; regular: { backgroundColor: string; }; smallBtn: { ...; }; }; cardVariants: { ...; }; }, "buttonVariants" | "cardV...' is not assignable to type 'RestyleFunctionContainer<VariantProps<{ spacing: { s: number; m: number; l: number; }; colors: { btnTextColor: string; }; breakpoints: { phone: number; tablet: number; }; buttonVariants: { defaults: {}; regular: { backgroundColor: string; }; smallBtn: { ...; }; }; cardVariants: { ...; }; }, "cardVariants", "variant"...'.
    Type 'VariantProps<{ spacing: { s: number; m: number; l: number; }; colors: { btnTextColor: string; }; breakpoints: { phone: number; tablet: number; }; buttonVariants: { defaults: {}; regular: { backgroundColor: string; }; smallBtn: { ...; }; }; cardVariants: { ...; }; }, "cardVariants", "variant">' is not assignable to type 'VariantProps<{ spacing: { s: number; m: number; l: number; }; colors: { btnTextColor: string; }; breakpoints: { phone: number; tablet: number; }; buttonVariants: { defaults: {}; regular: { backgroundColor: string; }; smallBtn: { ...; }; }; cardVariants: { ...; }; }, "buttonVariants" | "cardVariants", "variant">'.
      Types of property 'variant' are incompatible.
        Type 'ResponsiveValue<"regular" | "elevated", { phone: number; tablet: number; }> | undefined' is not assignable to type 'ResponsiveValue<"regular", { phone: number; tablet: number; }> | undefined'.
          Type '"elevated"' is not assignable to type 'ResponsiveValue<"regular", { phone: number; tablet: number; }> | undefined'.ts(2322)

Platform:

  • iOS
  • Android

Environment

@shopify/restyle: 2.4.1

Hey! I'm still looking into the root cause of this, in the meantime though can you try adding the variant's name in the angle brackets of the createVariant function as follows:

const variant = createVariant<Theme, 'cardVariants'>({
  themeKey: "cardVariants",
});

This should remove the TS error you observed while allowing you to have different keys for different variants. Please let me know if that works, thanks!

commented

@mattfrances Hey, thanks for the reply! Yes, adding the variant's name does the trick!