如何让TypeScript识别enabled为true时dataId必已定义?
React Query中TypeScript类型绑定的优雅解决方案
原代码及问题
export const useDataQuery = ({ dataId, enabled = Boolean(dataId), }: { dataId?: string; enabled?: boolean; }) => { return useQuery({ queryKey: [DATA_ID, dataId], enabled, queryFn: async () => { const data = await getData(dataId); return data; }, }); };
已知逻辑:
- 当
enabled为假值时,queryFn不会执行 - 只要
dataId已定义,enabled默认设为true - 但TypeScript仍判定
getData(dataId)中的dataId可能为undefined
优雅解决方案:用联合类型约束参数
通过定义联合类型的Props,让TypeScript明确参数间的依赖关系:当enabled为true时,dataId必须存在;若dataId未定义,则enabled必须为false。
// 定义参数的联合类型 type UseDataQueryProps = // 提供dataId时,enabled可选(默认true) { dataId: string; enabled?: boolean } // 不提供dataId时,enabled必须为false | { dataId?: undefined; enabled: false }; export const useDataQuery = ({ dataId, enabled = dataId !== undefined, }: UseDataQueryProps) => { return useQuery({ queryKey: [DATA_ID, dataId], enabled, queryFn: async () => { // TypeScript可正确推断:此时dataId必然是string类型 const data = await getData(dataId); return data; }, }); };
方案优势
- 无需使用非空断言
dataId!或抛出错误,类型安全由TypeScript自动保障 - 保留了原有的灵活性:用户可显式设置
enabled: false(即使有dataId),也可让enabled自动根据dataId是否存在来决定 - 代码可读性更强,参数的约束关系通过类型定义一目了然
内容的提问来源于stack exchange,提问作者Konrad
相关产品推荐
相关产品推荐

