如何在具有对象语法和 TypeScript 的样式组件中使用 shouldForwardProps?

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

我已经尝试了所有方法,但无法弄清楚语法(这里是 TS Playground):

const BASE_CONFIG = {
  shouldForwardProp: (
    prop: string,
    defaultValidatorFn: (prop: string) => boolean
  ) => prop !== 'isSmallContainer' && defaultValidatorFn(prop),
};

const Thing = styled(
  'div',
  BASE_CONFIG
)<{
  isSmallContainer: boolean;
}>(({ isSmallContainer }) => ({
  padding: isSmallContainer ? 12 : '16px 32px',
  display: 'flex',
  alignItems: 'center',
}));

预期有 1 个参数,但得到了 2 个。

我原来的定义没有

shouldForwardProps

const Thing = styled.div<{
  isSmallContainer: boolean;
}>(({ isSmallContainer }) => ({
  padding: isSmallContainer ? 12 : '16px 32px',
  display: 'flex',
  alignItems: 'center',
}));

我应该在哪里放置配置并且还有 TypeScript 语法和对象表示法(而不是样式组件模板字符串)?

另一次尝试:

const Thing = styled
  .div<{
    isSmallContainer: boolean;
  }>(({ isSmallContainer }) => ({
    padding: isSmallContainer ? 12 : '16px 32px',
    display: 'flex',
    alignItems: 'center',
  }))
  .withConfig(BASE_CONFIG);

该表达式不可调用。输入“never”没有呼叫签名。

const Thing = styled
  .div<{
    isSmallContainer: boolean;
  }>.withConfig(BASE_CONFIG)(({ isSmallContainer }) => ({
    padding: isSmallContainer ? 12 : '16px 32px',
    display: 'flex',
    alignItems: 'center',
  }));

实例化表达式后面不能跟属性访问。

还没想明白。

const Thing = styled.withConfig(BASE_CONFIG).div<{
  isSmallContainer: boolean;
}>(({ isSmallContainer }) => ({
  padding: isSmallContainer ? 12 : '16px 32px',
  display: 'flex',
  alignItems: 'center',
}));

类型“StyledInterface”上不存在属性“withConfig”。

typescript styled-components
2个回答
1
投票

在您在这里使用的所有 API 中,您都错误地使用了它们。我已经在this TS Playground 链接中注释了您所犯的错误。 但我也会在这里添加它 -

// original
const Thing = styled.div<{
  isSmallContainer: boolean;
}>(({ isSmallContainer }) => ({
  // padding: isSmallContainer ? 12 : '16px 32px',
  // The type of padding in the library is `string & {} | 0` so you can either set it to zero or a string
  padding: isSmallContainer ? "12px" : '16px 32px',
  display: 'flex',
  alignItems: 'center',
}));

const Thing2 = styled(
  'div',
  // The function takes only one argument so can't take BASE_CONFIG
  // BASE_CONFIG 
)<{
  isSmallContainer: boolean;
}>(({ isSmallContainer }) => ({
  // padding: isSmallContainer ? 12 : '16px 32px',
  // The type of padding in the library is `string & {} | 0` so you can either set it to zero or a string
  padding: isSmallContainer ? "12px" : '16px 32px',
  display: 'flex',
  alignItems: 'center',
}));

const Thing3 = styled
  .div<{
    isSmallContainer: boolean;
  }>(({ isSmallContainer }) => ({
    // padding: isSmallContainer ? 12 : '16px 32px',
    // The type of padding in the library is `string & {} | 0` so you can either set it to zero or a string
    padding: isSmallContainer ? "12px" : '16px 32px',
    display: 'flex',
    alignItems: 'center',
  }))
  // Not Supported by API
  // .withConfig(BASE_CONFIG);

const Thing4 = styled
  .div<{
    isSmallContainer: boolean;
  }>
  // .withConfig(BASE_CONFIG) Cannot call a generic
  (({ isSmallContainer }) => ({
    // padding: isSmallContainer ? 12 : '16px 32px',
    // The type of padding in the library is `string & {} | 0` so you can either set it to zero or a string
    padding: isSmallContainer ? "12px" : '16px 32px',
    display: 'flex',
    alignItems: 'center',
  }));

const Thing5 = styled("div")
// .withConfig(BASE_CONFIG) // The params are incorrect
.withConfig({ shouldForwardProp: (prop) => prop === "isSmallContainer" ? false : true })
// Already called styled with `div` argument, no need to call again
// .div<{
//   isSmallContainer: boolean;
// }>
<{isSmallContainer: boolean}>(({ isSmallContainer }) => ({
  // padding: isSmallContainer ? 12 : '16px 32px',
  // The type of padding in the library is `string & {} | 0` so you can either set it to zero or a string
  padding: isSmallContainer ? "12px" : '16px 32px',
  display: 'flex',
  alignItems: 'center',
}));

0
投票
const BASE_IGNORED_PROPS: Array<string | number | symbol> = [
  'isSmallContainer',
];

const BASE_CONFIG: StyledConfig<
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  StyledComponentPropsWithRef<React.ComponentType<any>>
> = {
  shouldForwardProp: (
    prop: string | number | symbol,
    defaultValidatorFn: (prop: string | number | symbol) => boolean
  ) => !BASE_IGNORED_PROPS.includes(prop) && defaultValidatorFn(prop),
};

const Thing = styled.div(({ theme }) => ({
  flex: '0 1 100%',
}));

const ThingInner = styled(Flex).withConfig(BASE_CONFIG)<{
  isSmallContainer: boolean;
}>(({ isSmallContainer }) => ({
  width: '100%',
  padding: isSmallContainer ? 12 : 32,
  paddingBottom: 0,
}));
© www.soinside.com 2019 - 2024. All rights reserved.