Rah*_*dhi 7 typescript reactjs material-ui
尝试扩展 Material-ui Button 组件以添加新道具。
目的是添加一个新道具:fontSize它有三个选项 - small、medium、large。
Run Code Online (Sandbox Code Playgroud)<Button variant="outlined" color="primary" fontSize="small"> button_small </Button>
并在 css 中使用它来进行所需的更改。
根据typescript 主题定制的材料 ui 文档,我已经定制了主题并且工作正常。
唯一的问题是尝试更新 Button 的道具类型不起作用。
我收到此错误是因为没有重载匹配,这很明显,因为 Material ui Button 组件不知道“fontSize”新道具。
错误 TS2769:没有与此调用匹配的重载。
重载 1 of 3, '(props: { href: string; } & { children?: ReactNode; color?: Color | undefined; disabled?: boolean | undefined; disableElevation?: boolean | undefined; disableFocusRipple?: boolean | undefined; ... 5 更多...; 变体?:“文本” | ... 2 更多... | 未定义; } & { ...; } & CommonProps<...> & Pick<...>) : 元素',出现以下错误。输入'{孩子:字符串;变体:“概述”;颜色:“原色”;字体大小:字符串;}' 不可分配给类型 'IntrinsicAttributes & { href: string; } & { 孩子?:ReactNode; 颜色?:颜色 | 不明确的; 禁用?:布尔值 | 不明确的; disableElevation?: boolean | 不明确的; ……还有6个……;变体?:“文本” | ... 2 更多... | 不明确的; } & { ...; } & CommonProps<...> & Pick<...> '。属性 'fontSize' 不存在于类型 'IntrinsicAttributes & { href: string; } & { 孩子?:ReactNode; 颜色?:颜色 | 不明确的; 禁用?:布尔值 | 不明确的; disableElevation?: boolean | 不明确的; ……还有6个……;变体?:“文本” | ... 2 更多... | 不明确的; } & { ...; } & CommonProps<...> & Pick<...>'。
重载 2 of 3, '(props: { component: ElementType; } & { children?: ReactNode; color?: Color | undefined; disabled?: boolean | undefined; disableElevation?: boolean | undefined; ... 6 more .. .; 变体?: "text" | ... 2 more ... | undefined; } & { ...; } & CommonProps<...> & Pick<...>): Element', 给出以下内容错误。类型“{children: string;”中缺少属性“component” 变体:“概述”;颜色:“原色”;字体大小:字符串;}' 但在类型 '{ component: ElementType; 中是必需的 }'。
重载 3 of 3, '(props: DefaultComponentProps<ExtendButtonBaseTypeMap<ButtonTypeMap<{}, "button">>>): Element',出现以下错误。输入'{孩子:字符串;变体:“概述”;颜色:“原色”;字体大小:字符串;}' 不可分配到类型 'IntrinsicAttributes & { children?: ReactNode; 颜色?:颜色 | 不明确的; 禁用?:布尔值 | 不明确的; disableElevation?: boolean | 不明确的; ……还有6个……;变体?:“文本” | ... 2 更多... | 不明确的; } & { ...; } & CommonProps<...> & Pick<...>'。属性 'fontSize' 不存在于类型 'IntrinsicAttributes & { children?: ReactNode; 颜色?:颜色 | 不明确的; 禁用?:布尔值 | 不明确的; disableElevation?: boolean | 不明确的; ……还有6个……;变种?:“
尝试 1:根据此堆栈溢出问题的答案, 我尝试重新声明 Button,但它引发了一个似乎未解决的打字稿错误 ( https://github.com/Microsoft/TypeScript/issues/17547 )。
declare module '@material-ui/core' {
export interface MyButtonProps {
fontSize: 'small' | 'medium' | 'large';
}
export class Button extends StyledComponent<ButtonProps & MyProps> {
}
}
Run Code Online (Sandbox Code Playgroud)
Attempt2:试图覆盖 ButtonTypeMap 而不是 Button 但这也无济于事。
declare module '@material-ui/core/Button' {
export type ButtonTypeMap<P = {}, D extends React.ElementType<any> = "button"> = ExtendButtonBaseTypeMap<{
props: P & {
children?: React.ReactNode;
color?: CustomColors;
disabled?: boolean;
disableElevation?: boolean;
disableFocusRipple?: boolean;
endIcon?: React.ReactNode;
fullWidth?: boolean;
href?: string;
size?: 'small' | 'medium' | 'large';
startIcon?: React.ReactNode;
variant?: 'text' | 'contained';
fontSize: 'small' | 'medium' | 'large';
};
defaultComponent: D;
classKey: ButtonClassKey;
}>
// The next line throws error with 'Button' is already declared in the upper scope
// declare const Button: ExtendButtonBase<ButtonTypeMap>;
}
Run Code Online (Sandbox Code Playgroud)
版本:
打字稿: 4.2.4
@material-ui/核心: 4.11.4
编辑:这里有一些答案(/sf/answers/4574119721/),它添加了一个自定义 HOC,它扩展了 material-ui 组件以实现所需的行为,但我想覆盖材料 UI 组件本身只是为了与从“ material-ui”而不是从我的本地自定义组件文件夹导入组件保持一致。
您可以简单地使用ButtonProps和扩展它并添加自定义属性以及扩展所有其余属性。
import {
Button as MuiButton,
ButtonProps,
makeStyles
} from "@material-ui/core";
interface IButtonProps extends ButtonProps {
fontSize?: "small" | "medium" | "large";
}
const useStyles = makeStyles({
small: {
fontSize: "0.7em"
},
medium: {
fontSize: "1.0em"
},
large: {
fontSize: "1.4em"
}
});
function Button({ fontSize = "medium", children, ...rest }: IButtonProps) {
const classes = useStyles();
return (
<MuiButton classes={{ label: classes[fontSize] }} {...rest}>
{children}
</MuiButton>
);
}
export default Button;
Run Code Online (Sandbox Code Playgroud)
您将拥有 MUI 按钮的每个道具以及自定义道具,以自动完成,例如fontSize:
<div className="buttons">
<Button
fontSize="small"
variant="contained"
onClick={() => console.log("small button")}
>
Small
</Button>
<Button
fontSize="medium"
variant="contained"
onClick={() => console.log("medium button")}
>
Medium
</Button>
<Button
fontSize="large"
variant="contained"
onClick={() => console.log("large button")}
>
Large
</Button>
</div>
Run Code Online (Sandbox Code Playgroud)
您可以在此CodeSandBox React TS 演示应用程序中尝试具有完整代码完成的工作示例。
PS:如果您使用 ESLint,请不要忘记通过禁用规则来允许 JSX Props Spreading react/jsx-props-no-spreading。
import {
Button as MuiButton,
ButtonProps,
makeStyles
} from "@material-ui/core";
interface IButtonProps extends ButtonProps {
fontSize?: "small" | "medium" | "large";
}
const useStyles = makeStyles({
small: {
fontSize: "0.7em"
},
medium: {
fontSize: "1.0em"
},
large: {
fontSize: "1.4em"
}
});
function Button({ fontSize = "medium", children, ...rest }: IButtonProps) {
const classes = useStyles();
return (
<MuiButton classes={{ label: classes[fontSize] }} {...rest}>
{children}
</MuiButton>
);
}
export default Button;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
704 次 |
| 最近记录: |