Button 组件使用 Partial 定义交叉类型后报错
来源:4-11 精益求精 - Buton 组件编码第二部分

Lawliet_ZMZ
2020-05-04
/**
* @file Button
*/
import React from 'react';
import classNames from 'classnames';
// Button 尺寸
export enum ButtonSize {
Large = 'large',
Small = 'small',
}
// Button 类型
export enum ButtonType {
Primary = 'primary',
Default = 'default',
Danger = 'danger',
Link = 'link',
}
// 定义 Button 属性类型
interface BaseButtonProps {
className?: string;
disabled?: boolean;
size?: ButtonSize;
type?: ButtonType;
href?: string;
children: React.ReactNode;
}
// 定义交叉类型
type NativeButtonProps = BaseButtonProps &
React.ButtonHTMLAttributes<HTMLElement>;
type AnchorButtonProps = BaseButtonProps &
React.AnchorHTMLAttributes<HTMLElement>;
export type ButtonProps = Partial<NativeButtonProps & AnchorButtonProps>;
function Button(props: ButtonProps) {
// 解构属性
const {
disabled,
className,
size,
type,
href,
children,
...restProps
} = props;
// 定义 class
const classes = classNames('button', className, {
[`button-${type}`]: type,
[`button-${size}`]: size,
disabled: type === ButtonType.Link && disabled,
});
if (type === ButtonType.Link) {
return (
<a className={classes} href={href} {...restProps}>
{children}
</a>
);
} else {
return (
<button className={classes} disabled={disabled} {...restProps}>
{children}
</button>
);
}
}
Button.defaultProps = {
disabled: false,
type: ButtonType.Default,
children: '',
};
export default Button;
这是 Button 组件的代码,报错信息提示:
/Users/jackwang/Documents/ComponentLibrary/feather-ui/src/App.tsx
TypeScript error in /Users/jackwang/Documents/ComponentLibrary/feather-ui/src/App.tsx(7,15):
Type 'ButtonType.Link' is not assignable to type 'undefined'. TS2322
5 | return (
6 | <div>
> 7 | <Button type={ButtonType.Link} href="https://jack-wjq.top">
| ^
8 | 你好
9 | </Button>
10 | <Button type={ButtonType.Primary}>你好</Button>
index.tsx 部分的代码:
import React from 'react';
import Button, { ButtonSize, ButtonType } from './components/Button/Button';
function App() {
return (
<div>
<Button type={ButtonType.Link} href="https://jack-wjq.top">
你好
</Button>
<Button type={ButtonType.Primary}>你好</Button>
<Button type={ButtonType.Danger} size={ButtonSize.Large}>
test
</Button>
<Button size={ButtonSize.Small}>你好</Button>
</div>
);
}
export default App;
由于 TS 水平不是很好,还请老师看一看这部分的问题出在呐?
写回答
1回答
-
同学你好 做的很认真,在课中我们故意把这个属性称之为 btnType 是有原因的,因为 button 和 link 这两个接口都有默认的 type 属性,
interface AnchorHTMLAttributes<T> extends HTMLAttributes<T> { type?: string; } interface ButtonHTMLAttributes<T> extends HTMLAttributes<T> { type?: 'submit' | 'reset' | 'button'; }
你在这里再使用交叉类型,由于重名,会导致最终的 type 变成 undefined,两个解决方法,
第一个:换名字,非常简单,就不会重名啦!
第二个:将AnchorHTMLAttributes 和 ButtonHTMLAttributes 都 type 属性都去掉,可以使用 typescript 内置的 Omit 方法。
type NativeButtonProps = BaseButtonProps & Omit<ButtonHTMLAttributes<HTMLElement>, 'type'> type AnchorButtonProps = BaseButtonProps & Omit<AnchorHTMLAttributes<HTMLElement>, 'type'>
这样 那两个接口 都没有 type 属性啦,也就没问题了。
522021-06-05
相似问题