使用any类型对象展开传参时TS停止校验?是否为预期行为?
TypeScript扩展运算符配合any时的Props校验差异
现象复现
组件定义(Component.tsx)
import React from "react"; export const Component = ({ title, subTitle }: Props) => { return ( <div> <h1>{title}</h1> <p>{subTitle}</p> </div> ); }; type Props = { title: string; subTitle: string; };
场景1:使用扩展运算符传参(无校验错误)
import { Component } from "./Component"; import "./styles.css"; export default function App() { const componentData: any = { title: "Hello", subTitle: "Hello from comp" }; return ( <div className="App"> {/* 尽管randomProp不在Component的Props中,TS未报错 */} <Component {...componentData} randomProp="string" /> </div> ); }
场景2:直接传参(触发校验错误)
import { Component } from "./Component"; import "./styles.css"; export default function App() { const componentData: any = { title: "Hello", subTitle: "Hello from comp" }; return ( <div className="App"> <Component title={componentData.title} subTitle={componentData.subTitle} {/* TS此处报错:类型“{ title: any; subTitle: any; randomProp: string; }”的参数不能赋给类型“Props”的参数。对象文字可以只指定已知属性,并且“randomProp”不在类型“Props”中。 */} randomProp="string" /> </div> ); }
结论:这是TypeScript的预期行为,并非Bug
底层机制解析
any类型的“传染性”:TypeScript中
any类型会覆盖其他类型的校验逻辑——当你用any类型的对象通过扩展运算符传递属性时,扩展后的整个props对象会被推断为any类型,TypeScript会完全跳过对这个对象的属性校验,包括后续额外添加的randomProp。扩展运算符与直接传参的类型处理差异:
- 扩展运算符场景:
{...componentData, randomProp: "string"}会被合并为any类型(因为componentData是any),而any可以赋值给任何类型,所以不会触发错误。 - 直接传参场景:每个属性是单独传递的,虽然
componentData.title和componentData.subTitle是any(可以兼容Props中的string类型),但randomProp是明确的字符串类型,TypeScript会直接对比Props类型,发现不存在该属性,因此抛出错误。
- 扩展运算符场景:
内容的提问来源于stack exchange,提问作者Dan Bacila
相关产品推荐
相关产品推荐

