【问题标题】:How to properly extend a styled component using TypeScript如何使用 TypeScript 正确扩展样式化组件
【发布时间】:2019-03-25 23:03:00
【问题描述】:

根据 styled-components v4,.extend 已弃用,扩展或组合组件的正确方法是:

const ButtonA = styled('button')`color: ${props => props.color};`
const ButtonB = styled(ButtonA)`background: 'white';`

但是我找不到使用 TS 执行此操作的正确方法,因为我遇到了一些错误,例如:

import styled from "styled-components";

// Let's create ButtonA
type ButtonAProps = { a: string };
const ButtonA = styled<ButtonAProps, "button">("button")`
  color: ${props => props.a};
`;

// So, here is what I've tried

// Fail #1
// =======
type ButtonBProps = { b: string };
const ButtonB = styled<ButtonBProps, ButtonAProps>(ButtonA)`
  background: ${props => props.b};
`; // Here I get autocompletion only for B props :(
const Test = () => <ButtonB a="something" />; // And here I get autocompletion only for A props :(

// Fail #2
// =======
type ButtonBProps = { b: string } & ButtonAProps;
const ButtonB = styled<ButtonBProps, ButtonAProps>(ButtonA)`
  background: ${props => props.b};
`; //  Here I get autocompletion for A & B props, good!
const Test = () => <ButtonB a="something" />; // Here I still get autocompletion only for A props :(

// Fail #3
// =======
type ButtonBProps = { b: string } & ButtonAProps;
const ButtonB = styled<ButtonBProps, ButtonBProps>(ButtonA)` // Property 'b' is missing in type 'ButtonAProps', of course
  background: ${props => props.b};
`; //  Here I get "props has implicitly any type"
const Test = () => <ButtonB />; // Here I don't get any type checking at all

似乎快到了,但无法弄清楚。

有什么建议吗?谢谢!

【问题讨论】:

    标签: reactjs typescript styled-components


    【解决方案1】:

    这似乎对我有用:

    type ButtonBProps = { b: string };
    const ButtonB = styled<ButtonAProps>(ButtonA)<ButtonBProps>`
      background: ${props => props.b};
    `;
    const Test = () => <ButtonB a="something" b="somethingelse" />;
    

    @types/styled-components 声明很难理解(带有无用的类型参数名称 PTOU)并且显然没有记录,所以我不能确定这是预期的方法.我找到了a related issue,但似乎并没有证实这种做法。

    【讨论】:

    • 谢谢你,当然可以!不过,如果有一个更简洁的方法会很好,就像联合类型或从主界面扩展一样。
    • 其实用最新的 typescript 你就可以做到styled(A)&lt;B&gt;
    • 这对我有用,我不需要父类型,就像其他人提到的 styled(A)
    【解决方案2】:

    截至 2019 年 9 月,以下代码也可以使用:

    // First extend ButtonAProps with an additional prop
    interface ButtonBProps extends ButtonAProps {
      b:string;
    }
    
    // ButtonB Component
    const ButtonB = styled(ButtonA)<ButtonBProps>`
      background: ${props => props.b};
    `;
    

    【讨论】:

    • extends here 是可选的,styled-components 足够聪明,可以推断父类型;一个简单的styled(ButtonA)&lt;{b: string}&gt; 也可以,你仍然会扩展 ButtonProps
    【解决方案3】:

    截至 2021 年 10 月,@Zalaboza 在 cmets 中的回答对我帮助最大,也是最简单的实现。

    Styled-components 足够聪明,可以推断父类型:

    styled(ButtonA)<{b: string}>
    

    【讨论】:

      猜你喜欢
      • 2020-01-09
      • 2020-05-02
      • 2019-12-16
      • 2019-03-28
      • 2020-06-12
      • 2019-02-22
      • 2021-06-02
      • 1970-01-01
      • 2020-11-05
      相关资源
      最近更新 更多