TypeScript中NextPage组件两种props类型标注有何区别
两种写法确实有实际类型区别,核心差异在会不会自动给props加上children类型支持,本质是TypeScript的类型推断优先级规则导致的。
先捋两个基础背景:
NextPage<Props>是Next.js提供的页面组件类型,从你IDE的提示能看出来,你当前用的依赖版本里,这个类型约定的组件入参默认是React.PropsWithChildren<Props>,会给你传入的自定义Props自动补一个可选的children字段类型。React.PropsWithChildren<T>是React内置的工具类型,实现非常简单,就是T & { children?: React.ReactNode },作用就是给组件属性快速加上子元素的类型定义。
第一种写法:不手动标注props类型,完全靠上下文推断
// tooltip says: (parameter) props: React.PropsWithChildren<MyAppProps> const IndexPage: NextPage<MyAppProps> = (props) => {...}
这种写法是TS里推荐的标准写法:你已经给IndexPage这个变量标了NextPage<MyAppProps>类型,TS会自动顺着这个类型反推函数参数props的类型,也就是IDE提示的React.PropsWithChildren<MyAppProps>。
这种场景下,哪怕你自己写的MyAppProps里完全没提children字段,在组件里直接用props.children也不会报类型错,类型是自动带上的。
第二种写法:手动给props标注MyAppProps类型
// tooltip says: (parameter) props: MyAppProps const IndexPage: NextPage<MyAppProps> = (props: MyAppProps) => {...}
这种写法相当于你手动给函数参数指定了类型,直接覆盖了TS从NextPage推出来的默认参数类型。这时候props的类型就完全是你自定义的MyAppProps,不会自动追加children字段。
要是你没在MyAppProps里手动写children?: React.ReactNode,后面在组件里访问props.children的时候,TS会直接抛错,说你的类型上不存在这个属性。
实际开发建议
完全没必要写第二种重复标类型的代码,属于费力不讨好,很容易不小心丢掉内置的类型。如果确实要手动写参数类型,要么直接用推断出来的
React.PropsWithChildren<MyAppProps>,要么记得在自己的MyAppProps里补上需要的children类型。
额外提一句:这种默认带children的表现和依赖版本有关系,React18之后官方的React.FC已经移除了默认的children注入,部分高版本Next.js的App Router页面类型也不会自动补children,你现在的IDE提示已经说明你本地装的Next版本对应的NextPage是默认带children类型的。
内容的提问来源于stack exchange,提问作者Abdul Mahamaliyev

