如何使用 Typescript 扩展 Material-UI 组件的道具?
Posted
技术标签:
【中文标题】如何使用 Typescript 扩展 Material-UI 组件的道具?【英文标题】:How to extend props for Material-UI components using Typescript? 【发布时间】:2018-02-19 12:33:16 【问题描述】:我想使用 typescript 从 Material-UI 扩展 Button 组件的道具,以便能够将其他道具传递给它的孩子。
import NavLink from 'react-router-dom';
import Button from 'material-ui';
<Button
component=NavLink
// NavLink props that needs to be added to typescript declarations
activeClassName=classes.activeButton
exact=true
to=to
>
title
</Button>
我尝试在 ./app/types/material_ui.d.ts 中添加以下声明:
declare module 'material-ui'
interface Button
activeClassName?: any;
exact?: boolean;
to?: string;
这会引发错误“TS2693:'Button' 仅指一种类型,但在此处用作值。”。
我也尝试过声明:
import * as React from 'react';
import PropTypes, StyledComponent from 'material-ui';
import ButtonBaseProps from 'material-ui/ButtonBase';
declare module 'material-ui'
export interface ButtonProps extends ButtonBaseProps
color?: PropTypes.Color | 'contrast';
component?: React.ReactNode;
dense?: boolean;
disabled?: boolean;
disableFocusRipple?: boolean;
disableRipple?: boolean;
fab?: boolean;
href?: string;
raised?: boolean;
type?: string;
activeClassName?: any;
exact?: boolean;
to?: string;
export class Button extends StyledComponent<ButtonProps>
这会引发错误“TS2323:无法重新声明导出的变量 'Button'”。
我的 tsconfig.json 看起来像这样:
"compilerOptions":
...
"paths":
"history": ["./node_modules/@types/history/index"],
"redux": ["./node_modules/@types/redux/index"],
"react": ["./node_modules/@types/react/index"],
"*": ["./app/types/*", "*"]
,
,
...
最后是来自 Material-UI 的原始类型定义:
import * as React from 'react';
import StyledComponent, PropTypes from '..';
import ButtonBaseProps from '../ButtonBase';
export interface ButtonProps extends ButtonBaseProps
color?: PropTypes.Color | 'contrast';
component?: React.ReactNode;
dense?: boolean;
disabled?: boolean;
disableFocusRipple?: boolean;
disableRipple?: boolean;
fab?: boolean;
href?: string;
raised?: boolean;
type?: string;
export default class Button extends StyledComponent<ButtonProps>
我正在使用 material-ui 1.0.0-beta.8 和 react 15.6.1、react-router-dom 4.2.2 和 typescript 2.5.2。
【问题讨论】:
【参考方案1】:import React, FC from 'react';
import Button, ButtonProps from '@material-ui/core';
interface IProps extends ButtonProps // your custom props
const ButtonHco: FC<IProps> = (
variant,
color,
children,
size,
disabled
) =>
return (
<Button variant=variant color=color size=size disabled=disabled>
children
</Button>
);
;
export default ButtonHco;
【讨论】:
谢谢,它有效。有人知道在哪里可以找到和提取 Box 的“justifyContent”属性的默认值吗?【参考方案2】:以下代码对我有用
import Button, StyledComponent from 'material-ui';
import ButtonProps from 'material-ui/Button';
declare module 'material-ui'
export interface MyProps
exact?: boolean;
to?: string;
export class Button extends StyledComponent<ButtonProps & MyProps>
"TS2693: 'Button' only refers to a type, but is being used as a value here.
没有问题,我也在使用 Typescript 2.5.2
【讨论】:
看起来很简单,但对我来说这行不通。我收到以下错误:TS2323:无法重新声明导出的变量“Button”。 TS2484:导出声明与“Button”的导出声明冲突。这可能与 @987654321 有关@。有什么想法吗? 有趣,这是另一个issue,你能创建一个最小的可重现回购吗? @eitido 我知道已经两年了,但是对于其他来到这里的人来说,原因是 Button 是一个 MUI 组件,而您正在尝试创建自己的 Button 组件,所以这是一个命名冲突.您只需将 MUI 的按钮别名为MuiButton
(或其他名称)。
它只是不起作用。它对其他人有用吗?【参考方案3】:
这是一个扩展 Material UI 按钮的简约示例(未经测试)。 扩展字段将简单地附加在按钮标签之后。
import * as React from 'react';
import ButtonProps from '@material-ui/core/Button';
import Button from '@material-ui/core';
interface Props
extendedField: string;
export class MyExtendedButton extends React.Component<ButtonProps & Props>
render()
const
extendedField,
children,
...buttonProps,
= this.props;
return (<Button ...buttonProps>
children
: <span style=color: 'red'>
extendedField
</span>
</Button>);
【讨论】:
非常有帮助,感谢分享基于类的示例 :)【参考方案4】:有点晚了,但这是另一种解决方案。另请参阅 MUI 文档 Usage of component prop 。 以下按钮使用 Link 组件。它还使用 Link 的特定道具及其类型。它还添加了自己的 sesific 道具。
import React from 'react'
import MuiButton, ButtonProps from '@material-ui/core/Button'
interface ButtonOptions
// your custom options with their types
const Button = <C extends React.ElementType>(props: ButtonProps<C, component?: C> & ButtonOptions ) =>
return <MuiButton ...props>props.children</MuiButton>
export default Button
// use like this:
import Link from 'react-router-dom'
<Button component=Link to='/somelocation'>
【讨论】:
以上是关于如何使用 Typescript 扩展 Material-UI 组件的道具?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Typescript 扩展 Material-UI 组件的道具?
如何使用 Typescript 在 React 中扩展 HTML 属性
如何使用具有多个页面和入口点的 React 和 TypeScript 设置 chrome 扩展?