简体   繁体   English

使用带有打字稿的样式组件的“as”多态属性

[英]Using 'as' polymorphic prop of styled-components with typescript

I was trying to implement a Typography react component.我试图实现一个 Typography 反应组件。
As you can see below, I got variant as an input prop and used it as index of VariantsMap object to get corresponding html tag name.正如您在下面看到的,我将变体作为输入道具并将其用作 VariantsMap 对象的索引以获取相应的 html 标签名称。

Then I used styled-components 'as' polymorphic prop to render it as selected html tag.然后我使用styled-components 'as' 多态道具将其呈现为选定的 html 标签。

but I keep get this error :但我不断收到此错误:
No overload matches this call. Overload 1 of 2, '(props: Omit<Omit<Pick<DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "key" | keyof HTMLAttributes<...>> & { ...; } & { ...; }, never> & Partial<...>, "theme"> & { ...; } & { ...; }): ReactElement<...>', gave the following error. Type 'string' is not assignable to type 'undefined'.

I found in @types/styled-component that 'as' props can be 'never |我在@types/styled-component 中发现“as”道具可以是“never | undefined', and my variantsMap returns string type. undefined',我的变体映射返回字符串类型。
But I really want to use this 'as' prop with my variant-specific html tag selection feature.但我真的想将这个 'as' 道具与我的特定于变体的 html 标签选择功能一起使用。

Is there any way to solve this problem?有没有办法解决这个问题?

const variantMap = {
  h1: 'h1',
  h2: 'h2',
  h3: 'h3',
  h4: 'h4',
  h5: 'h5',
  h6: 'h6',
  subheading1: 'h6',
  subheading2: 'h6',
  body1: 'p',
  body2: 'p',
};

export const Typography = ({ variant : string }) => { 

      const selectedComponent = variantMap[variant];

      return (<TypographyRoot
        as={selectedComponent}
        variant={variant}
        {...props}
      >
        {children}
      </TypographyRoot>);
}

First of all, export const Typography = ({ variant : string }) => {} is invalid syntax.首先, export const Typography = ({ variant : string }) => {}是无效语法。

You just changed the name of destructured variant to string .您刚刚将解构variant的名称更改为string You did not provide a type.您没有提供类型。

The reason you have an error even with valid string type like here export const Typography = ({ variant }:{variant: string}) => {} is that variantMap expects as a key h1 |即使使用像这里这样的有效string类型也会出错的原因是export const Typography = ({ variant }:{variant: string}) => {}variantMap期望作为键h1 | 'h2' |'h3' ... keys whereas string is much wider. 'h2' |'h3' ... 键,而string要宽得多。 I'd willing to bet that you don't want to assign foo string to variant property.我敢打赌您不想将foo字符串分配给variant属性。

IN order to fix it, you just need to make variantMap immutable and apply appropriate constraint to variantMap :为了修复它,您只需要使variantMap不可变并将适当的约束应用于variantMap

import React from 'react'
import styled from "styled-components";

const Div = styled.div`
  color: red;
`;

const VariantMap = {
  h1: 'h1',
  h2: 'h2',
  h3: 'h3',
  h4: 'h4',
  h5: 'h5',
  h6: 'h6',
  subheading1: 'h6',
  subheading2: 'h6',
  body1: 'p',
  body2: 'p',
} as const;

type Props = {
  variant: keyof typeof VariantMap
}
export const Typography = ({ variant }: Props) => {

  const selectedComponent = VariantMap[variant];

  return <Div
    as={selectedComponent}
  />
}

Now styled-component is happy.现在styled-component很高兴。

Playground 操场

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM