如何在 Typescript 中使用道具在情感/样式样式组件之间共享样式

Posted

技术标签:

【中文标题】如何在 Typescript 中使用道具在情感/样式样式组件之间共享样式【英文标题】:How to share styles, with props, between emotion/styled styled components, in Typescript 【发布时间】:2021-11-01 10:54:43 【问题描述】:

我正在使用emotion styled components。我有一个textinput 和一个input,我希望它们具有相同的样式。我在 .tsx 文件中执行此操作(也就是说,我正在编写打字稿)。

我认为它应该看起来像这样:

someView.tsx

import styled from "@emotion/styled";
import  css  from "@emotion/react";


const InputStyling = css`
 width: 100%;
  border-style: solid;
  border-color: $(props:  invalid?: boolean ) => props.invalid ? red : blue;
`;

export const BaseInput = styled.input<invalid?: boolean>`
  $InputStyling
`;

export const BaseTextarea = styled.textarea<invalid?: boolean>`
  $InputStyling
`;

这不起作用,我在输入检查时收到以下错误:

➤ YN0000: src/design_system/TextInput/TextInput.tsx(19,22): error TS2769: No overload matches this call.
➤ YN0000:   Overload 1 of 2, '(template: TemplateStringsArray, ...args: CSSInterpolation[]): SerializedStyles', gave the following error.
➤ YN0000:     Argument of type '(props:     invalid?: boolean;) => string' is not assignable to parameter of type 'CSSInterpolation'.
➤ YN0000:       Type '(props:  invalid?: boolean | undefined; ) => string' is missing the following properties from type 'CSSInterpolation[]': pop, push, concat, join, and 25 more.
➤ YN0000:   Overload 2 of 2, '(...args: CSSInterpolation[]): SerializedStyles', gave the following error.
➤ YN0000:     Argument of type 'TemplateStringsArray' is not assignable to parameter of type 'CSSInterpolation'.
➤ YN0000:       Type 'TemplateStringsArray' is missing the following properties from type 'CSSInterpolation[]': pop, push, reverse, shift, and 6 more.

我浏览了许多 *** 的答案,尝试了上面略有不同的咒语。例如,我尝试使用interface:

interface InputBoi 
  invalid?: boolean


export const BaseInput = styled.input<InputBoi>`
  $resetInputCss
  $InputStyling
`;

我遇到了同样的错误。

我尝试使用styled 工厂函数样式:

export const BaseInput = styled('input')<InputBoi>`
  $resetInputCss
  $InputStyling
`;

export const BaseTextarea = styled('textarea')<invalid?: boolean>`
  $resetInputCss
  $InputStyling
`;

两者的错误相同。

Emotion's composition style isn't exactly what I want, 这个应用程序的结构强烈倾向于避免render 函数中的任何 CSS。

Other *** answers 处理扩展其他组件,但这不是我想做的,我想共享 css,而不是让一个组件扩展另一个组件(因为一个需要是 input 和另一个需要是textarea)。

在情感库,我找到了people with similar issues,但没有解决方案。

CSSObject 对我不起作用,我需要传递道具。

在打字稿文件中使用情感/样式样式组件时,在两个不同组件之间共享样式的正确方法是什么?

【问题讨论】:

【参考方案1】:

答案是使用返回styledcss模板字符串的函数,如下所示:

const getInputStyling = ( invalid  :  invalid: boolean | undefined) => css`
  width: 100%;
  border-color: $invalid ? 'red' : 'black';
`;

export const BaseInput = styled.input<invalid: boolean | undefined>`
  $(invalid) => getInputStyling( invalid )
`;

【讨论】:

以上是关于如何在 Typescript 中使用道具在情感/样式样式组件之间共享样式的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Vue3 中启用仅使用 TypeScript 的道具键入

如何在传递道具时使用 TypeScript 实现“as”道具?

当父组件在其子组件中注入道具时,如何在 Typescript 中定义道具?

在没有道具的 Typescript 中使用 React.forwardRef

如何使用 Typescript 在不丢失任何道具的情况下键入样式组件?

如何使用enum作为react / typescript中的道具