在React中使用TypeScript最有利的部分之一是能够拥有强类型的组件道具。这使得使用该组件的开发者能够快速了解他们可以传递什么,并帮助他们避免犯错。
在这篇文章中,我们将通过几种不同的方法来强类型化组件道具的功能。我们将对以下组件的props进行强类型化:
const TextField = ({
label,
text,
onTextChange
}) => (
<div>
<label>{label}</label>
<input
type="text"
value={text}
onChange={e =>
onTextChange(e.currentTarget.value)
}
/>
</div>
);
内联类型注解
也许最简单的方法是在props 函数参数上使用一个内联类型注释:
const TextField = ({
label,
text,
onTextChange
}: { label: string; text: string; onTextChange: (text: string) => void;}) => ...
当我们的组件中只有几个道具,而且这些道具不需要重复使用时,这是一个不错的方法。
如果组件是一个普通的函数而不是一个箭头函数,也可以使用这种方法:
function TextField({
label,
text,
onTextChange
}: { label: string, text: string, onTextChange: (text: string) => void}) { ...
}
类型别名
我们可以将道具提取到一个类型别名中:
type Props = { label: string; text: string; onTextChange: (text: string) => void;};const TextField = ({
label,
text,
onTextChange
}: Props) => ...
当至少有几个道具,或者我们想在多个组件中重复使用道具类型时,这种方法很好。
同样,这种方法也可以用于常规函数组件:
function TextField({
label,
text,
onTextChange
}: Props) ...
接口
我们可以使用一个接口来代替类型别名:
interface Props {
label: string;
text: string;
onTextChange: (text: string) => void;
}
现在接口的功能与类型别名非常相似,所以一般来说,使用哪种接口是个人的偏好。
FC 类型
有一个标准的React类型,FC ,我们可以在箭头函数组件上使用。"FC "代表函数组件,它别名一个叫做FunctionComponent 的类型:
const TextField: React.FC<Props> = ({ label,
text,
onTextChange
}) => ...
FC 类型被用于分配给箭头函数的变量上。它是一个通用类型,我们将组件的道具类型传入其中。
使用FC 类型有一些可以争论的小好处:
FC在 上提供了一些类型安全,它可以用来为道具提供默认值。然而, 可能会在未来的版本中从 React 中删除。defaultPropsdefaultPropsFC包括了 道具类型,所以你不需要明确地定义它。然而,可以说,明确地定义它是更好的,这样消费者就可以肯定地知道这是否可用。children
扩展一个标准类型
props类型可以扩展一个标准类型:
interface Props
extends React.InputHTMLAttributes< HTMLInputElement > { label: string;
text: string;
onTextChange: (text: string) => void;
}
在上面的例子中,我们已经为一个input 元素扩展了标准的props类型。这意味着我们的组件现在可以接受诸如maxLength 和placeholder 等道具。
另外,我们也可以使用一个类型别名和交集来达到同样的效果:
type Props = React.InputHTMLAttributes< HTMLInputElement> & { label: string;
text: string;
onTextChange: (text: string) => void;
};