来自 react-jss 的带有 createUseStyles 的 TypeScript 类型

TypeScript Typings with createUseStyles from react-jss

我很难把我的打字改正,所以我很好奇是否有人有一个有效的例子或一些关于我哪里出错的反馈。对于这个 createUseStyles 实例,我需要做两件事,接受主题和道具。

我从文档网站上拿了这个例子,当然马上它就已经抛出了 TypeScript 错误,这是可以理解的:

(粘贴屏幕截图只是为了显示打字稿错误)

截图中的代码块:

import React, { ReactNode, CSSProperties } from "react";
import {
  createUseStyles,
  useTheme,
  ThemeProvider,
  DefaultTheme,
  Styles
} from "react-jss";

interface Props {
  children: ReactNode;
  useRed: boolean;
}

interface PUTheme {
  colorPrimary: string;
  altColor: string;
}

const useStyles = createUseStyles({
  button: {
    background: ({ theme }) => theme.colorPrimary
  },
  label: {
    fontWeight: "bold"
  }
});

const Button2: React.FC<Props> = ({ children, ...props }) => {
  const theme = useTheme();
  console.log(theme);
  const classes = useStyles({ ...props, theme });
  return (
    <button className={classes.button}>
      <span className={classes.label}>{children}</span>
    </button>
  );
};

const theme = {
  colorPrimary: "green",
  altColor: "red"
};

const App = () => (
  <ThemeProvider theme={theme}>
    <Button2 useRed={true}>I am a button 2 with green background</Button2>
  </ThemeProvider>
);

export default App;

这里发现的错误(错误1)是:

  button: {
    background: ({ theme }) => theme.colorPrimary
  },

Property 'colorPrimary' does not exist on type 'Theme'.ts(2339)

在一定程度上说得通 - 它不知道我们的主题包含什么,所以继续...

此处 (错误 2)theme 发现的错误是:

const classes = useStyles({ ...props, theme });

Type 'DefaultTheme' is not assignable to type 'Theme'. Type 'null' is not assignable to type 'Theme'.ts(2322)

马上..我有点困惑。但是,让我们输入一些内容,看看结果如何...

为我的主题添加界面似乎并没有改变上述任何错误:

interface PUTheme {
  colorPrimary: string;
  altColor: string;
}

const theme: PUTheme = {
  colorPrimary: "green",
  altColor: "red"
};

因此,由于向我的主题对象添加接口似乎并没有取得多大成就,因此我能够通过添加类型来满足 错误 1 的错误。虽然这让 TypeScript 平静下来,但感觉 错了吗?

const useStyles = createUseStyles({
  button: {
    background: ({ theme }: {theme: PUTheme}) => theme.colorPrimary
  },
  label: {
    fontWeight: "bold"
  }
});

然而,这仍然给我留下 错误 2 除了错误已经改变稍微

Type 'DefaultTheme' is not assignable to type 'PUTheme'. Type 'null' is not assignable to type 'PUTheme'

我已经尝试跟踪 react-jss 中的输入,但目前我可能无法理解。

有没有人对我做错了什么或工作示例有任何提示或见解?另外,这里有一个 link 到我的 code sandbox 如果你想看到它的实际效果。

你可以试试这样的咒语:

const useStyles = createUseStyles({
  button: {
    background: (theme: PUTheme) => theme.colorPrimary
  },
  label: {
    fontWeight: "bold"
  }
});

const Button2: React.FC<Props> = ({ children, ...props }) => {
  const theme = useTheme() as PUTheme;
  console.log(theme);
  const classes = useStyles(theme);
  return (
    <button className={classes.button}>
      <span className={classes.label}>{children}</span>
    </button>
  );
};

请注意,它不会将任何 props 传递给 useStyles。查看此函数的类型定义,它似乎只能接受 "Theme"

认为我找到了解决方案。 theme/props 传递给 类 对我来说仍然感觉很奇怪,但它有效并且满足 TypeScript。

import React, { ReactNode } from "react";
import { createUseStyles, useTheme, ThemeProvider } from "react-jss";

interface Props {
  children: ReactNode;
  useRed: boolean;
}

interface PUTheme {
  colorPrimary: string;
  altColor: string;
}

const useStyles = createUseStyles({
  button: {
    background: ({
      theme,
      useRed
    }: {
      theme: PUTheme;
      useRed: Props["useRed"];
    }) => (useRed ? theme.altColor : theme.colorPrimary)
  },
  label: {
    fontWeight: "bold"
  }
});

const Button2: React.FC<Props> = ({ children, ...props }) => {
  const theme = useTheme<PUTheme>();
  const classes = useStyles({ ...props, theme });
  return (
    <button className={classes.button}>
      <span className={classes.label}>{children}</span>
    </button>
  );
};

const theme: PUTheme = {
  colorPrimary: "green",
  altColor: "red"
};

const App = () => (
  <ThemeProvider theme={theme}>
    <Button2 useRed={true}>I am a button 2 with green background</Button2>
  </ThemeProvider>
);

export default App;

我认为缺少的主要内容是 useTheme 输入 const theme = useTheme<PUTheme>();

查看工作 Code Sandbox here!