如何使用 TypeScript 正确扩展样式组件

ric*_*res 6 typescript reactjs styled-components

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

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

但是,我找不到使用 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
Run Code Online (Sandbox Code Playgroud)

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

有什么建议吗?谢谢!

小智 7

截至 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};
`;
Run Code Online (Sandbox Code Playgroud)

  • 这里的 extends 是可选的,styled-components 足够智能来推断父类型;一个简单的 `styled(ButtonA)&lt;{b: string}&gt;` 也可以工作,你仍然可以扩展 ButtonProps (2认同)

Mat*_*hen 5

这似乎对我有用:

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

@types/styled-components声明是很难理解(有无益类型参数的名称PTOU),显然没有证件,所以我不能肯定这是否是预期的做法。我发现了一个相关的问题,但它似乎并没有证实这种方法。

  • 实际上,使用最新的打字稿你可以只做`styled(A)&lt;B&gt;` (3认同)