如何使用 TypeScript 以类型安全的方式访问 React 子元素道具?
Posted
技术标签:
【中文标题】如何使用 TypeScript 以类型安全的方式访问 React 子元素道具?【英文标题】:How to access React child element props in a type safe manner with TypeScript? 【发布时间】:2020-03-08 03:09:48 【问题描述】:我正在尝试在我的应用程序中访问 React [Native] 组件的 props
(保证是我的自定义类型 ItemTemplate
的元素的实例:
const children = React.Children.toArray(this.props.children);
return children.find(t => t.props.itemKey == key);
但是,当我尝试访问 t.props
时,在第二行中我得到:
Property 'props' does not exist on type 'ReactElement<ItemTemplate, string | ((props: any) => ReactElement<any, string | ... | (new (props: any) => Component<any, any, any>)> | null) | (new (props: any) => Component<any, any, any>)> | ... 13 more ... | (ReactElement<...>[] & ReactPortal)'.
Property 'props' does not exist on type 'ReactElement<ItemTemplate, string | ((props: any) => ReactElement<any, string | ... | (new (props: any) => Component<any, any, any>)> | null) | (new (props: any) => Component<any, any, any>)>[] & string'.
代码工作正常,但 TypeScript (3.6.3) IntelliSense 出现问题。 为什么?
【问题讨论】:
投反对票的人至少可以解释原因吗? 【参考方案1】:在这种情况下,您需要将子项声明或强制转换为 ReactElement。这里我有一个从 nextjs 到自定义 NavLink 的 Link 组件示例:
import ReactElement, cloneElement from 'react';
import Link, LinkProps from 'next/link';
type NavigationData =
currentPath: string;
pathsToMatch: string[] | string;
activeClassName: string;
children: ReactElement;
;
type NavLinkProps = LinkProps & NavigationData;
export default function NavLink(
currentPath,
pathsToMatch,
activeClassName,
children,
...props
: NavLinkProps): ReactElement
function GetActiveLink(
currentPath: string,
paths: string | string[],
activeClassName: string
): string
if (currentPath === '/' && paths === '/')
return activeClassName;
else if (currentPath !== '/' && paths.indexOf(currentPath) !== -1)
return activeClassName;
return '';
let className: string = children.props.className || '';
className += ` $GetActiveLink(currentPath, pathsToMatch, activeClassName)`;
return <Link ...props>cloneElement(children, className )</Link>;
通过这种方式,您可以在没有任何警告的情况下访问属性道具。
快乐的代码。 :-)
【讨论】:
【参考方案2】:如下使用:
const children: Array<ReactChild> = React.Children.toArray(this.props.children);
return children.find(t => t.props.itemKey == key);
或使用您的自定义类型 ItemTemplate:
const children: Array<ItemTemplate> = React.Children.toArray(this.props.children);
return children.find(t => t.props.itemKey == key);
【讨论】:
它不起作用。它不能将该类型分配给children
: ... Type 'ReactElementany
不应使用,除非将 javascript 迁移到 TypeScript。以上是关于如何使用 TypeScript 以类型安全的方式访问 React 子元素道具?的主要内容,如果未能解决你的问题,请参考以下文章
Typescript + Svelte - 如何添加类型以传播组件道具
typesafe 使用 reactjs 和 typescript 选择 onChange 事件
Javascript / Typescript:以角度将一个数组类转换为另一个数组类