React + Typescript + Styled Components 将道具传递给关键帧和调节

React + Typescript + Styled Components pass props to keyframes & conditioning

我正在尝试将道具传递给 keyframe 元素并制作一些条件动画。这是我的代码:

import styled, { keyframes } from "styled-components";
import {
  PRIMARY,
  SECONDARY,
  DANGER,
  TEXT,
  OUTLINE,
} from "../../constans";

interface PropTypes {
  color?: string;
  variant?: string;
  size?: string;
  shadow?: boolean;
  disabled?: boolean;
  hoverAnimation?: boolean;
}

const StyledButton = styled.button<PropTypes>`
  // [... SOME CODE ...]
  animation: ${(props) => hoverAnimate(props)} 2s infinite;
`;

const hoverAnimate = (props: PropTypes) => keyframes`
        100%{
            color: ${() => {
              console.log(props);
              if (props.variant) {
                if (props.color) {
                  return `var(--color-${props.color})`;
                }
                return "#444";
              }
              return "#fff";
            }};

            background: ${() => {
              if (props.variant === TEXT || props.variant === OUTLINE)
                return "#f00";
              console.log("object");
              if (props.color === PRIMARY) return "var(--color-primary)";
              if (props.color === SECONDARY) return "var(--color-secondary)";
              if (props.color === DANGER) return "var(--color-danger)";
              return "var(--color-default)";
            }};
        }
`;

我做错了什么?

TS抱怨:

Argument of type '() => string' is not assignable to parameter of type 'SimpleInterpolation'. Type '() => string' is missing the following properties from type 'readonly SimpleInterpolation[]': concat, join, slice, indexOf, and 17 more.

并且,console.log(props) 打印:

object

就像一根绳子。我无法在开发工具中扩展这个 object(即使尝试解构)。

您似乎正在尝试使用 IIFE (immediately invoked function expression) to return a "string" that would be used inside template strings

但是您遇到了 TypeScript 错误:

Argument of type '() => string' is not assignable to parameter of type 'SimpleInterpolation'.

因为您当前的代码:

const hoverAnimate = (props: PropTypes) => keyframes`
  100%{
    color: ${() => {
      if (props.variant) {
        if (props.color) {
          return `var(--color-${props.color})`;
        }
        return "#444";
      }
      return "#fff";
    }};
    ...

没有正确调用 IIFE。

以下是通过调用(注意额外的 ()s)IIFE 来修复它的方法:

const hoverAnimate = (props: PropTypes) => keyframes`
  100%{
    color: ${(() => { // Here, at start
      if (props.variant) {
        if (props.color) {
          return `var(--color-${props.color})`;
        }
        return "#444";
      }
      return "#fff";
    })()}; // And, here
    ...

您也需要为 background 做同样的事情。