使用打字稿进行反应组件子类型检查
Posted
技术标签:
【中文标题】使用打字稿进行反应组件子类型检查【英文标题】:React Component children typecheck with typescript 【发布时间】:2019-03-14 21:08:35 【问题描述】:这是场景:
我有一个自定义组件:
class MyComponent extends React.Component
render ()
return (
<SuperComponent>
<SubComponent1 /> // <- valid child
</SuperComponent>
)
class MyComponent extends React.Component
render ()
return (
<SuperComponent>
<SubComponent2 /> // <- No! It's not right shape
</SuperComponent>
)
并且引用的 SuperComponent 和 SubComponent1 是:
interface superPropsType =
children: ReactElement<subPropsType1>
class SuperComponent extends React.Component<superPropsType> ...
interface subPropsType1 =
name: string
class SubComponent1 extends React.Component<subPropsType1> ...
interface subPropsType2 =
title: string
class SubComponent2 extends React.Component<subPropsType2> ...
我希望 SubComponent1 是 SuperComponent 的唯一有效子代,也就是说,如果我将 <SubComponent2 />
或其他类型作为 <SuperComponent>
的子代,我希望 typescript 可以抛出错误
似乎 typescript 只检查子级是否应该具有 ReactElement 的类型,但 ts 不会检查该子级的道具形状(即 subPropsType1),也就是说,如果我将字符串或数字放置为SuperComponent 的子组件,ts 会抱怨类型要求不满足,但是如果我在这里放置任何 jsx 标签(将转译为 ReactElement),ts 将保持沉默
有什么想法吗?如果需要在此处发布任何配置,请随时询问
非常感谢任何想法和解决方案
【问题讨论】:
【参考方案1】:从 TypeScript 3.1 开始,所有 JSX 元素都被硬编码为 JSX.Element
类型,因此无法接受某些 JSX 元素而不接受其他元素。如果你想要这种检查,你将不得不放弃 JSX 语法,定义你自己的元素工厂函数来包装 React.createElement
但为不同的组件类型返回不同的元素类型,然后手动编写对该工厂函数的调用。
有an open suggestion,它可能会在 TypeScript 3.2(将于 2018 年 11 月下旬发布)尽快实现,以便 TypeScript 根据给定组件的工厂函数的实际返回类型为 JSX 元素分配类型类型。如果实现了,您将能够定义自己的工厂函数来包装React.createElement
并使用jsxFactory
编译器选项指定它,您将获得额外的类型信息。或者@types/react
甚至会改变,以便React.createElement
提供更丰富的类型信息,如果这样做不会对不关心功能的项目造成有害后果的话;我们将不得不拭目以待。
【讨论】:
【参考方案2】:我可能会将SuperPropsType.children
声明为:
children: React.ReactElement<SubPropsType1> | React.ReactElement<SubPropsType1>[];
考虑同时拥有一个和多个孩子的可能性。
无论如何,正如已经指出的那样,这不会按预期工作。
你可以做的是声明一个道具,比如说subComponentProps: SubPropsType1[]
,传递你需要的道具来创建那些SubComponent1
s,而不是它们的JSX,并在SuperComponent
中渲染它们:
interface SuperPropsType
children?: never;
subComponentProps?: SubPropsType1[];
...
const SuperComponent: React.FC<SuperPropsType> = ( subComponentProps ) =>
return (
...
subComponentProps.map(props => <SubComponent1 key= ... ...props />)
...
);
;
【讨论】:
以上是关于使用打字稿进行反应组件子类型检查的主要内容,如果未能解决你的问题,请参考以下文章