NextJS+TypeScript构建失败:Object is possibly 'undefined'错误求助
Next.js Build 时 TypeScript "Object is possibly 'undefined'" 错误解决
问题描述
我是TypeScript新手,代码在浏览器中运行正常,但执行nextjs build时出现类型错误,尝试过网上方法未解决,点击按钮会调用test函数。
错误信息
Type error: Object is possibly 'undefined'. 62 | useEffect(() => { 63 | if(value!.includes('javascript')){ > 64 | setJs(value!.split('```javascript').pop().split('```')[0]) | ^ 65 | } 66 | 67 | if (value!.includes('html')){
组件代码
const [value, setValue] = useState<string|null>('const pi = 3.14;'); const [loading, setLoading] = useState(true); const [html, setHtml]=useState('') const [css,setCss] = useState('') const [js,setJs] = useState('') useEffect(() => { if(value!.includes('javascript')){ setJs(value!.split('```javascript').pop().split('```')[0]) } if (value!.includes('html')){ setHtml(value!.split('```html').pop().split('```')[0]) } if (value!.includes('css')){ setCss(value!.split('```css').pop().split('```')[0]) } },[value]) const test = async () => { try { setValue('hi') } catch (error) { console.log(error); } };
tsconfig.json 配置
{ "compilerOptions": { "lib": ["dom", "dom.iterable", "esnext"], "allowJs": true, "skipLibCheck": true, "strict": true, "noEmit": true, "esModuleInterop": true, "module": "esnext", "moduleResolution": "bundler", "resolveJsonModule": true, "isolatedModules": true, "jsx": "preserve", "incremental": true, "plugins": [ { "name": "next" } ], "paths": { "@/*": ["./*"] } }, "include": [ "next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts" ], "exclude": ["node_modules"] }
问题根源
- 即便用了
value!非空断言,TypeScript严格模式下仍会关注后续调用的安全性,毕竟value的类型是string|null。 - 核心问题:
split()返回的数组调用pop()可能返回undefined,哪怕你判断了value.includes('xxx'),TypeScript也无法自动推断split('```xxx')后的数组一定有至少两个元素,因此认定pop()结果可能为undefined,后续调用split()就会触发错误。 - 浏览器能正常运行是因为测试数据都包含对应的标记,实际没触发
pop()返回undefined的情况,但TypeScript静态检查会提前识别这个潜在风险。
解决方法
步骤1:先做非空校验,移除冗余断言
在useEffect开头先判断value是否为空,后续代码TypeScript会自动推断value是string类型,无需再写value!:
if (!value) return;
步骤2:处理pop()可能返回undefined的情况
对每个代码块,先存储split结果,判断数组长度后再操作,同时用可选链?.和兜底值避免undefined:
修改后的完整useEffect代码:
useEffect(() => { if (!value) return; if (value.includes('javascript')) { const parts = value.split('```javascript'); if (parts.length > 1) { const content = parts.pop()?.split('```')[0] || ''; setJs(content); } } if (value.includes('html')) { const parts = value.split('```html'); if (parts.length > 1) { const content = parts.pop()?.split('```')[0] || ''; setHtml(content); } } if (value.includes('css')) { const parts = value.split('```css'); if (parts.length > 1) { const content = parts.pop()?.split('```')[0] || ''; setCss(content); } } }, [value]);
额外说明
parts.length > 1确保split后确实有分割内容,避免无效操作。parts.pop()?.split('```')[0] || ''中,?.处理pop()返回undefined的情况,|| ''保证最终传给状态的是字符串,符合useState的初始类型定义。
内容的提问来源于stack exchange,提问作者user3322378
相关产品推荐
相关产品推荐

