如何使用 TypeScript 正确扩展样式化组件
How to properly extend a styled component using TypeScript
根据 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
好像差不多了,就是想不通
有什么建议吗?谢谢!
这似乎对我有用:
type ButtonBProps = { b: string };
const ButtonB = styled<ButtonAProps>(ButtonA)<ButtonBProps>`
background: ${props => props.b};
`;
const Test = () => <ButtonB a="something" b="somethingelse" />;
@types/styled-components
声明很难理解(使用无用的类型参数名称 P
、T
、O
、U
)并且显然没有记录,所以我不能确定这是预期的方法。我找到了a related issue,但似乎并没有证实这种做法。
截至 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};
`;
截至 2021 年 10 月,@Zalaboza 在评论中的回答对我帮助最大,也是最简单的实现。
Styled-components 足够智能,可以推断父类型:
styled(ButtonA)<{b: string}>
根据 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
好像差不多了,就是想不通
有什么建议吗?谢谢!
这似乎对我有用:
type ButtonBProps = { b: string };
const ButtonB = styled<ButtonAProps>(ButtonA)<ButtonBProps>`
background: ${props => props.b};
`;
const Test = () => <ButtonB a="something" b="somethingelse" />;
@types/styled-components
声明很难理解(使用无用的类型参数名称 P
、T
、O
、U
)并且显然没有记录,所以我不能确定这是预期的方法。我找到了a related issue,但似乎并没有证实这种做法。
截至 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};
`;
截至 2021 年 10 月,@Zalaboza 在评论中的回答对我帮助最大,也是最简单的实现。
Styled-components 足够智能,可以推断父类型:
styled(ButtonA)<{b: string}>