【问题标题】:styled-system props typing with TypeScript使用 TypeScript 键入的样式系统道具
【发布时间】:2019-05-11 16:40:23
【问题描述】:

我正在使用styled-system,库的一个关键是使用速记道具来轻松快速地进行主题化。

我已经简化了我的组件,但有趣的是:

import React from 'react'
import styled from 'styled-components'
import { color, ColorProps } from 'styled-system'

const StyledDiv = styled('div')<ColorProps>`
  ${color}
`

const Text = ({ color }: ColorProps) => {
  return <StyledDiv color={color} />
}

我在 color 道具上有一个错误,上面写着:

键入'字符串 | (字符串 | 空)[] | undefined' 不可分配给 输入'字符串 | (字符串 & (字符串 | null)[]) |未定义'。

我认为这是因为 styled-system 使用与原生 HTML 属性 color 相同的命名,并且会发生冲突。

我该如何解决这个问题?

【问题讨论】:

    标签: javascript reactjs typescript styled-components


    【解决方案1】:

    不要使用ColorProps,而是尝试使用color: CSS.ColorProperty(`import * as CSS from 'csstype');这是一个要点,展示了我如何使用 typescript/styled-system 创建一些类型化的“Box”原语:https://gist.github.com/chiplay/d10435c0962ec62906319e12790104d1

    祝你好运!

    【讨论】:

    • 这不是选择不使用 styled-system 的响应数组值作为颜色属性的能力吗?
    【解决方案2】:

    color 似乎在 HTMLAttributes 下的 react 声明文件中声明 - 它没有被导出。

    我必须通过创建 custom prop 来解决这个问题

    示例使用@emotion/styled,但也适用于styled-components

    // component.js
    import styled from '@emotion/styled';
    import { style, ResponsiveValue } from 'styled-system';
    import CSS from 'csstype';
    
    const textColor = style({
      prop: 'textColor',
      cssProperty: 'color',
      key: 'colors'
    });
    
    
    type Props = {
      textColor?: ResponsiveValue<CSS.ColorProperty>
    }
    
    const Box = styled.div<Props>`
      ${textColor};
    `
    
    export default Box;
    
    // some-implementation.js
    import Box from '.';
    
    const Page = () => (
      <Box textColor={['red', 'green']}>Content in a box</Box>
    );
    

    【讨论】:

      【解决方案3】:

      我所做的是使用 Typescript 转换功能并保持样式系统逻辑完整。例如:

      const Heading: React.FC<ColorProps> = ({ color, children }) => {
        return <HeadingContainer color={(color as any)} {...props}>{children}</HeadingContainer>;
      };
      

      【讨论】:

        【解决方案4】:

        以 Chris 的回答为基础,并使用 custom props 上的最新文档。

        // core/constants/theme.ts
        // Your globally configured theme file
        export const theme = { colors: { primary: ['#0A43D2', '#04122B'] } }
        
        // core/constants/styledSystem.ts
        import {
          color as ssColor,
          ColorProps as SSColorProps,
          TextColorProps,
          compose,
          system,
        } from 'styled-system'
        
        // Styled-system patch for the color prop fixing "Types of property 'color' are incompatible"
        // when appling props to component that extend ColorProps.
        export interface ColorProps extends Omit<SSColorProps, 'color'> {
          textColor?: TextColorProps['color']
        }
        
        export const color = compose(
          ssColor,
          system({
            // Alias color as textColor
            textColor: {
              property: 'color',
              // This connects the property to your theme, so you can use the syntax shown below E.g "primary.0".
              scale: 'colors'
            }
          })
        )
        
        // components/MyStyledComponent.ts
        import { color, ColorProps } from 'core/constants/styledSystem.ts'
        
        interface MyStyledComponentProps extends ColorProps {}
        
        export const MyStyledComponent = styled.div<MyStyledComponentProps>`
          ${color}
        `
        
        // components/MyComponent.ts
        export const MyComponent = () => <MyStyledComponent textColor="primary.0">...
        

        编辑:更新到 styled-components ^5.0.0 修复了这个问题

        https://github.com/styled-components/styled-components/blob/master/CHANGELOG.md#v500---2020-01-13

        【讨论】:

          【解决方案5】:

          只是添加到 xuanlopez' 的答案 - 不确定 5.0.0 版本具体解决了什么问题 - 但使用 $color 作为重命名的道具而不是 textColor 将其指定为样式组件中的 transient prop 所以作为道具,它不会出现在渲染的 DOM 中。

          【讨论】:

            猜你喜欢
            • 2020-11-14
            • 2019-04-13
            • 2019-08-05
            • 2021-12-13
            • 2020-12-27
            • 2021-01-13
            • 2020-02-03
            • 2020-09-10
            • 2019-10-10
            相关资源
            最近更新 更多