TypeScript下React条件渲染组件Visible无法触发类型收窄如何解决
问题根源
TypeScript 静态类型分析不会跨组件作用域推导变量状态,你在Visible组件内部对condition的真值判断,无法影响父组件作用域内banana变量的类型,因此原写法无论怎么调整返回值类型都无法实现自动类型收窄。
解决方案
改造Visible为泛型+Render Props模式,将收窄后的有效值通过参数传递给子渲染函数,让TS可以直接识别参数的非空类型:
改造后的Visible.ts代码
import { Fragment, type ReactNode } from 'react'; interface VisibleProps<T> { condition: T; children: (validated: NonNullable<T>) => ReactNode; } export function Visible<T>(props: VisibleProps<T>): ReactNode { const { condition, children } = props; if (!condition) return null; return <Fragment>{children(condition as NonNullable<T>)}</Fragment>; }
改造后的使用示例
const [banana, setBanana] = useState<undefined|string[]>(["foo","bar"]) return ( <Visible condition={banana}> {/* 此处拿到的validatedBanana会被自动收窄为string[]类型,无类型报错 */} {(validatedBanana) => ( <ul> {validatedBanana.map(e => <li key={e}>{e}</li>) } </ul> )} </Visible> )
可选兼容方案
如果不愿意改原有组件用法,可以手动在可能为空的变量后加非空断言!告知TS变量非空:
{banana!.map(e => <li key={e}>{e}</li>) }
该方案无需修改组件,但类型安全性由开发者手动保证,适合临时快速修改场景。
内容的提问来源于stack exchange,提问作者randomsab
相关产品推荐
相关产品推荐

