如何让TypeScript识别提取为独立变量的非空判断,消除变量未定义警告?
问题原因
这是TypeScript控制流类型分析的固有特性:它无法将独立布尔变量hasLoaded的真值,和fundsWeight、fakeTradeInfo两个变量的非空状态做关联推导。只有直接在if条件中对变量本身做非空校验时,才会触发对应变量的类型缩小,去掉空类型的可能性。
可用解决方案
以下方案均不需要使用非空断言,完全类型安全:
方案1:使用类型谓词封装校验逻辑(最推荐,可复用)
自定义一个带类型谓词的校验函数,显式告诉TypeScript:当函数返回值为true时,入参的两个变量都是非空状态。
// 定义校验函数,返回值带类型谓词 function isLoaded( fundsWeight: SomeRandomArray[] | undefined, fakeTradeInfo: SomeRandomObject | null ): fundsWeight is SomeRandomArray[] & fakeTradeInfo is SomeRandomObject { return !!fundsWeight && !!fakeTradeInfo; } // 组件内使用 const StackOverflow = ({ row }: { row: INewTradeState }) => { const fundsWeight = useSelector((state: RootState) => state.fakeFund.fundsWeight[row.univers.uniqueid]); const fakeTradeInfo = useSelector((state: RootState) => getFakeTradesInfoById(state)(row.id)); if (isLoaded(fundsWeight, fakeTradeInfo)) { return ( <> <TextField variant="outlined" label="ccy" value={fakeTradeInfo.ccy} /> <TextField variant="outlined" label="fx" value={fakeTradeInfo.fx} /> {fundsWeight.map((fund) => ( <>Do Stuff</> ))} </> ); } return <>not loaded</>; };
方案2:用对象包装变量后校验
如果不想单独封装函数,可以把两个变量放到同一个对象中,TypeScript可以跟踪对象属性的类型缩小,校验通过后解构使用即可:
const StackOverflow = ({ row }: { row: INewTradeState }) => { const fundsWeight = useSelector((state: RootState) => state.fakeFund.fundsWeight[row.univers.uniqueid]); const fakeTradeInfo = useSelector((state: RootState) => getFakeTradesInfoById(state)(row.id)); const loadState = { fundsWeight, fakeTradeInfo }; const hasLoaded = loadState.fundsWeight && loadState.fakeTradeInfo; if (hasLoaded) { // 解构后两个变量都会被识别为非空 const { fundsWeight, fakeTradeInfo } = loadState; return ( <> <TextField variant="outlined" label="ccy" value={fakeTradeInfo.ccy} /> <TextField variant="outlined" label="fx" value={fakeTradeInfo.fx} /> {fundsWeight.map((fund) => ( <>Do Stuff</> ))} </> ); } return <>not loaded</>; };
内容的提问来源于stack exchange,提问作者Nicolas Menettrier
相关产品推荐
相关产品推荐

