无法为React组件type属性的displayName找到匹配的TypeScript类型
解决React元素displayName的TypeScript类型报错问题
我明白你遇到的问题了——虽然运行时能正常获取displayName,但TypeScript因为默认类型定义的限制,报错说JSXElementConstructor<any>上不存在这个属性。咱们一步步来修复这个问题:
第一步:修正node的类型定义
你之前用Parameters<typeof React.isValidElement>作为node的类型是不对的,因为Parameters返回的是参数的数组类型(这里是[React.ReactElement<any, any> | null | undefined])。正确的做法是直接用React.ReactElement,或者取数组的第一个元素:
// 两种写法都可以,直接用React.ReactElement更直观 const node = SomeThingUnknown as React.ReactElement; // 或者用Parameters的第一个元素 // const node = SomeThingUnknown as Parameters<typeof React.isValidElement>[0];
第二步:扩展类型支持displayName
TypeScript的JSXElementConstructor联合类型(包含函数组件和类组件)默认没有包含displayName和name属性的定义,我们可以自定义一个扩展类型来补上:
type ComponentWithDisplayName = React.JSXElementConstructor<any> & { displayName?: string; name?: string; };
第三步:安全获取displayName
现在把node.type断言为我们自定义的类型,再执行你从React仓库参考的逻辑,就不会有类型报错了:
const type = node.type as ComponentWithDisplayName; const displayName = typeof type === "function" ? type.displayName || type.name || "Unknown" : type;
更严谨的类型守卫写法(可选)
如果想让类型检查更严格,避免不必要的断言,可以写一个类型守卫函数:
function isFunctionComponentWithNames( component: unknown ): component is { displayName?: string; name?: string } { return typeof component === "function"; } // 使用类型守卫处理 const type = node.type; let displayName: string; if (typeof type === "string") { displayName = type; } else if (isFunctionComponentWithNames(type)) { displayName = type.displayName || type.name || "Unknown"; } else { displayName = "Unknown"; }
这样处理后,VS Code的类型提示就会正常识别displayName和name属性,同时保留运行时的正确性。
内容的提问来源于stack exchange,提问作者Mats
相关产品推荐
相关产品推荐

