新建NextJS项目复制示例组件出现Missing prop报错咨询
问题成因
这类“属性已明确定义但TS提示缺失”的报错,在跨沙箱复制React+TS组件到本地NextJS项目时非常常见,核心触发原因有三个:
- 类型依赖版本不匹配:在线沙箱会默认锁定适配当前示例的TypeScript版本、
@types/react类型包版本,哪怕手动把沙箱的React版本切到18,底层的类型定义包版本、TS版本还是和沙箱初始配置对齐的。全新NextJS项目默认拉取的是最新版@types/react,新版本对原生表单元素、forwardRef的泛型约束做了收紧,和示例组件里写的类型推导逻辑不兼容,就会抛出属性缺失的错误。 - TS校验规则差异:在线沙箱默认会放宽TS严格校验规则,不少示例的tsconfig里
strict字段是关闭的,不会校验交叉类型、可选属性的隐式问题。NextJS默认开启全量严格模式校验,组件里如果用了隐式类型合并(比如直接把RHF返回的field属性展开透传给input,没有显式声明类型),严格模式下就会判定属性不匹配。 - React Hook Form版本差:RHF从V7早期版本到最新的V7.x版本,多次调整了
UseControllerProps、field返回值的类型结构,如果本地项目装的RHF版本和沙箱里的版本差超过3个小版本,就会出现属性对不上的类型错误。
解决方法
按以下优先级排查操作,不需要改业务逻辑就能解决问题:
- 对齐核心依赖版本
先在沙箱的依赖面板里查三个核心包的精确版本号:typescript、react-hook-form、@types/react,本地项目安装完全一致的版本,不要自行升级大版本,安装命令参考:
安装完成后重启编辑器的TS服务即可看到效果。npm install react-hook-form@<对应版本号> npm install -D @types/react@<对应版本号> typescript@<对应版本号> - 补全Input组件的显式类型声明
不要依赖TS自动推导合并RHF属性和原生input属性,手动给组件声明明确的props类型,修正forwardRef的泛型定义,参考写法:import { InputHTMLAttributes, forwardRef } from 'react'; import { UseControllerProps } from 'react-hook-form'; type InputProps = InputHTMLAttributes<HTMLInputElement> & { label?: string; errorText?: string; } & UseControllerProps; const Input = forwardRef<HTMLInputElement, InputProps>( ({ label, errorText, ...fieldProps }, ref) => { return ( <div className="form-input-wrap"> {label ? <label className="input-label">{label}</label> : null} <input ref={ref} {...fieldProps} className="base-input" /> {errorText ? <span className="input-error">{errorText}</span> : null} </div> ); } ); Input.displayName = 'FormInput'; export default Input; - 校验严格模式影响
如果前两步操作完还有报错,可以临时打开项目根目录的tsconfig.json,把compilerOptions下的strict字段设为false,重启TS服务后如果报错消失,说明原组件的类型声明存在隐式any或者可选属性漏写的问题,补全对应类型即可,不建议长期关闭TS严格模式。
注意:不要直接把沙箱的tsconfig.json内容复制覆盖本地NextJS项目的tsconfig,NextJS对配置项有内置约束,随意覆盖会引发路由、服务端渲染相关的类型异常。
内容的提问来源于stack exchange,提问作者Millenial2020
相关产品推荐
相关产品推荐

