【问题标题】:How to hoist non react statics with typescript and styled-components?如何使用打字稿和样式组件提升非反应静态?
【发布时间】:2018-12-28 03:31:59
【问题描述】:

我有一个静态的三个静态属性(HeaderBodyFooter)设置为Dialog 组件。但是,typescript 将 Dialog 组件包装在 styled-components 中后会引发以下错误。

Property 'Header' does not exist on type 'StyledComponentClass...

这是我的/Dialog.tsx

import { Dialog as BlueprintDialog, IDialogProps } from '@blueprintjs/core';
import * as React from 'react';
import styled from 'styled-components';

import Body from './Dialog.Body';
import Footer from './Dialog.Footer';
import Header from './Dialog.Header';

/** ************************************************************************* */

type DefaultProps = {
  className: string;
};

export interface DialogProps extends IDialogProps {
  children?: React.ReactNode;
  className?: string;
  primary?: boolean;
}

class Dialog extends React.PureComponent<DialogProps> {
  static displayName = 'UI.Dialog';
  static defaultProps: DefaultProps = {
    className: '',
  };
  static Body: typeof Body;
  static Footer: typeof Footer;
  static Header: typeof Header;
  render() {
    return <BlueprintDialog {...this.props} />;
  }
}

/** ************************************************************************* */

export default styled(Dialog)``;

这是我的index.ts,我将它们拼凑在一起:

import Dialog from './Dialog';
import DialogBody from './Dialog.Body';
import DialogFooter from './Dialog.Footer';
import DialogHeader from './Dialog.Header';

Dialog.Body = DialogBody; // TS Compilation Error :/
Dialog.Footer = DialogFooter; // TS Compilation Error :/
Dialog.Header = DialogHeader; // TS Compilation Error :/
export default Dialog;

我已尝试执行以下操作,但现在插值对于根 Dialog 组件失败:

import { Dialog as BlueprintDialog, IDialogProps } from '@blueprintjs/core';
import * as React from 'react';
import styled from 'styled-components';

import Body from './Dialog.Body';
import Footer from './Dialog.Footer';
import Header from './Dialog.Header';

/** ************************************************************************* */

type DefaultProps = {
  className: string;
};

export interface DialogProps extends IDialogProps {
  children?: React.ReactNode;
  className?: string;
  primary?: boolean;
}

class Dialog extends React.PureComponent<DialogProps> {
  static displayName = 'UI.Dialog';
  static defaultProps: DefaultProps = {
    className: '',
  };
  render() {
    return <BlueprintDialog {...this.props} />;
  }
}

/** ************************************************************************* */

const Styled = styled(Dialog)``;

class WithSubmodules extends Styled {
  static Body: typeof Body;
  static Footer: typeof Footer;
  static Header: typeof Header;
}

export default WithSubmodules;

引发Cannot call a class as a function 错误的插值示例:

export default styled(InterpolationExample)`
  ${Dialog.Header} { /* WORKS :) */
    border: 1px solid green;
  }
  ${Dialog} { { /* Throws Error :/ */
    border: 1px solid pink;
  }
`;

【问题讨论】:

    标签: javascript reactjs typescript styled-components


    【解决方案1】:

    所以我做了一些修改并得到了一些工作。如果有人有更好的方法,请告诉我!

    我最终做的是从styled-components 导入StyledComponentClass,然后通过以下方式使用静态属性对其进行扩展:

    interface WithSubmodules extends StyledComponentClass<DialogProps, {}> {
      Body: typeof Body;
      Footer: typeof Footer;
      Header: typeof Header;
    }
    

    接下来,我将返回的StyledComponent 转换为我的新扩展类型WithSubmodules

    export default styled(Dialog)`` as WithSubmodules;
    

    一切都在这里:

    import { Dialog as BlueprintDialog, IDialogProps } from '@blueprintjs/core';
    import * as React from 'react';
    import styled, { StyledComponentClass } from 'styled-components';
    
    import Body from './Dialog.Body';
    import Footer from './Dialog.Footer';
    import Header from './Dialog.Header';
    
    /** ************************************************************************* */
    
    type DefaultProps = {
      className: string;
    };
    
    export interface DialogProps extends IDialogProps {
      children?: React.ReactNode;
      className?: string;
      primary?: boolean;
    }
    
    class Dialog extends React.PureComponent<DialogProps> {
      static displayName = 'UI.Dialog';
      static defaultProps: DefaultProps = {
        className: '',
      };
      render() {
        return <BlueprintDialog {...this.props} />;
      }
    }
    
    /** ************************************************************************* */
    
    interface WithSubmodules extends StyledComponentClass<DialogProps, {}> {
      Body: typeof Body;
      Footer: typeof Footer;
      Header: typeof Header;
    }
    
    export default styled(Dialog)`` as WithSubmodules;
    

    再次提醒,如果有人有更好的方法,请告诉我!

    谢谢

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-11
      • 2021-06-07
      • 2020-06-27
      • 2019-07-17
      • 2023-03-06
      • 2020-06-03
      相关资源
      最近更新 更多