theme-ui icon indicating copy to clipboard operation
theme-ui copied to clipboard

Support custom theme types in TS bindings

Open ersinakinci opened this issue 3 years ago • 2 comments

Is your feature request related to a problem? Please describe. When using the sx prop, the useThemeUI hook, or any other API that exposes the theme object, it would be really nice to have a way to set a custom theme type for that object on a project-wide basis. So when I write

<div sx={{ backgroundImage: ({ colors: { red, blue } }) => `linear-gradient(to right, red, blue)` }} />

tsc shouldn't throw an error, which it currently does because the default Theme type's properties are all optional (so the compiler has no way of knowing whether colors exists on the theme object).

Describe the solution you'd like We should somehow be able to use generics to solve this problem:

  1. Leave out the ambient type that extends JSX elements with the sx prop. Explain how to extend the JSX interface with your own theme type in the docs. It should look something like this (whereas SxProps isn't currently generic):
import { SxProps } from '@theme-ui/core';

declare module 'react' {
  interface DOMAttributes<T> extends SxProps<MyTheme> {}
}
declare global {
  namespace JSX {
    interface IntrinsicAttributes extends SxProps<MyTheme> {}
  }
}
  1. Rewrite the useThemeUI hook in a way that takes advantage of a generic type and explain how to use this feature in the docs. Something like:
import { useThemeUI } from 'theme-ui';

export const useTheme = useThemeUI<MyTheme>;
  1. Repeat step 2 for all the other functions/API's in the Theme UI ecosystem that are currently hardwired to use the non-generic Theme type. For example, @theme-ui/color.

Describe alternatives you've considered I developed a brute-force workaround by disabling Theme UI's types in tsconfig.json and manually redefining the ones that define the theme object and related API's.

Additional context Original issue described here: https://github.com/system-ui/theme-ui/issues/1188#issuecomment-719016511

ersinakinci avatar Oct 29 '20 21:10 ersinakinci

Note that my proposed solution is an opt-in approach. The generic types should all fall back to the default Theme type, both to preserve current behavior and to allow for correct typing in scenarios where you genuinely don't know what properties will be available on a theme object. The latter may occur, for example, when using unvalidated, user-authored themes.

ersinakinci avatar Oct 29 '20 21:10 ersinakinci

Connected to https://github.com/system-ui/theme-ui/pull/1090.

hasparus avatar Nov 02 '20 07:11 hasparus