样式化组件和 TypeScript - 😍

2025-06-04

样式化组件和 TypeScript - 😍

Styled Components恰好是我最喜欢的 JS 库中的 CSS 之一,并且几乎是我所有ReactJS项目的一部分

在我把大部分项目迁移到 TypeScript 的过程中,有些地方我遇到了一些问题,但也有一些地方感觉很完美。这里列出其中一些。

1. 安装类型

Styled Components 库本身不包含类型。因此,我们必须从Definitely Typed仓库中安装它。

npm i --save-dev @types/styled-components

2.自定义道具

使用 CSS-in-JS 解决方案的主要优势之一是能够在运行时传递自定义 props 并相应地调整 CSS。

const Heading = styled.h1<{ active: boolean }>`
  color: ${(props) => props.active ? "red" : "blue"};
`;

就像在 JSX 元素中一样,你可以在<>组件后传递泛型类型。现在,你的 styled-component 已经具备类型,如果你没有传递activeprop,元素上就会出现静态错误。

要使用它来扩展组件:

import Title from "./Title";

const Heading = styled(Title)<{ active: boolean }>`
  color: ${(props) => props.active ? "red" : "blue"};
`;

但是,请注意,即使没有明确说明,active也会将 prop 传递给组件。如果有人稍后向组件添加可选 prop,这可能会有问题。为了避免这种情况,你可以使用 refractor 来:Titleactive

const Heading = styled(({active, ...rest}) => <Title {...rest} />)<{ active: boolean }>`
  color: ${(props) => props.active ? "red" : "blue"};
`;

然而,这种语法显然更加复杂,并且会产生一个额外的组件。至于是否值得为了意外发现一个 prop 而付出这么多,则取决于你。

3. 输入主题

Styled Components 能够借助 指定主题ThemeProvider。稍后您可以使用 访问theme${props=>props.theme.main.something}即使我们忽略了其他所有内容,仅主题对象的自动完成功能就值得我们这样做。

来自文档:

第一步是创建一个声明文件。我们来举styled.d.ts个例子。

// import original module declarations
import 'styled-components'

// and extend them!
declare module 'styled-components' {
  export interface DefaultTheme {
    borderRadius: string

    colors: {
      main: string
      secondary: string
    }
  }
}

但是像这样手动输入主题很麻烦,主要是因为每次在主题对象中添加或删除内容时都必须编辑两个不同的文件。你可以这样做:

import {} from "styled-components";
import theme from "../theme";

declare module "styled-components" {
  type Theme = typeof theme;
  export interface DefaultTheme extends Theme {}
}

在这里,我们利用 Typescript 的类型推断来为theme我们完成对象🙌。

4. 利用css道具

css出于某种原因,Styled Components 文档中有两个函数。这里我指的是启用Babel 插件css后可以在元素上使用的属性。

<div
  css={`display: flex;`}
>
...

</div>

但是 TypeScript 无法识别这个css属性,所以报错了。我不知道你是怎么想的,但那些红线确实让我很困扰👻。

为了解决这个问题,您可以将以下内容添加到styled.d.ts

import {} from "styled-components";
import { CSSProp } from "styled-components";

declare module "react" {
  interface Attributes {
    css?: CSSProp | CSSObject;
  }
}

5.媒体模板

从文档中可以很容易地指定媒体查询,但是虽然它的语法对用户友好,但对于 TypeScript 来说,其实现本身很难推理(事实上,对于新用户来说也是如此)。

相反,我发现自己使用了一种更简单的替代方法:

const customMediaQuery = (maxWidth: number) =>
  `@media (max-width: ${maxWidth}px)`;

const media = {
  custom: customMediaQuery,
  desktop: customMediaQuery(922),
  tablet: customMediaQuery(768),
  phone: customMediaQuery(576)
};

const Content = styled.div`
  height: 3em;
  width: 3em;
  background: papayawhip;

  /* Now we have our methods on media and can use them instead of raw queries */
  ${media.desktop} {
    background: dodgerblue;
  }
  ${media.tablet} {
    background: mediumseagreen;
  }
  ${media.phone} {
    background: palevioletred;
  }
`;

render(<Content />);

礼貌

我仍然有一个痛点是关于ref。将 添加到样式组件仍然会给我一个错误,就像一年前ref一样

否则,样式化组件💙TypeScript。

最初发布在我的博客上

文章来源:https://dev.to/boywithsilverwings/styled-components-typescript-e28
PREV
Docker 化 React 应用
NEXT
7 个可帮助您节省时间的 NPM 命令