带有打字稿中带样式的组件的默认道具

问题描述 投票:0回答:1

我正在处理一个包含几个默认道具的组件,我想将它们传递给一个样式组件。这是我目前在的位置:

import React, { FC } from "react";
import styled from "styled-components";
// Icon SVG code
import Icons from "./icons";

const icons = ["add", "subtract"];

interface Props {
  className?: string;
  icon: typeof icons[number];
  size?: number;
}

const Wrapper = styled.div<Omit<Props, "icon">>(({ size }) => ({
  width: size,
  height: size
}));

const Icon: FC<Props> = ({ className, icon, size = 24 }) => (
  <Wrapper className={className} size={size}>
    <Icons icon={icon} />
  </Wrapper>
);

对于顶级组件API,size应该为可选属性,因为它具有默认值(24)。但是,size应该标记为Wrapper样式的组件所必需的,因为React会确保如果开发人员未提供默认值,则始终应用默认值。

我想知道是否有人对设计模式提出建议以解决此问题,而不必多次重写同一接口的变体。我还在使用所有依赖项的最新版本,包括TS,React和样式化组件。

非常感谢!

reactjs typescript styled-components
1个回答
0
投票

如果我对您的理解正确,此类型可能会有所帮助

type RequireKey<T, Key> = { [K in keyof Required<T>]: K extends Key ? NonNullable<T[K]> : T[K] }

要创建不能再定义大小的Props的修改版,您可以执行

// The original Props that is Wrapper's external interface
interface Props {
  className?: string;
  icon: typeof icons[number];
  size?: number;
}

// Props with "size" made mandatory
type RequireSize = RequireKey<Props, "size">
//
// type RequireSize = {
//     className: string | undefined;
//     icon: string;
//     size: number; // <- no longer optional!
// }

// Omits "icon" as before but now "size" is required
const Wrapper = styled.div<Omit<RequireSize, "icon">>(({ size }) => ({
  width: size,
  height: size
}));

// Use Props as before
const Icon: FC<Props> = ({ className, icon, size = 24 }) => (
  <Wrapper className={className} size={size}>
    <Icons icon={icon} />
  </Wrapper>
);
© www.soinside.com 2019 - 2024. All rights reserved.