You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何TypeScript中{}允许非空值,而FC<{}>却不接受任意Props?

React TypeScript 中空接口{}作为组件Props的矛盾解析

问题背景

React TypeScript Cheatsheet中明确:空接口{}和Object类型代表任意非空值,而非字面意义上的“空对象”。以下TypeScript代码可验证该结论:

let value: {};

value = 1;
value = "foo";
value = () => alert("foo");
value = {};
value = { foo: "bar" };

value = undefined; // 类型错误
value = null;  // 类型错误

从示例可见,{}类型可匹配数字、字符串、函数、任意非空对象等,但无法赋值undefined或null。

基于这个认知,当组件定义为FC<{}>时,似乎Props应能接受任意非空值作为属性,但实际传递{ id: '1111' }时却触发类型错误:

const Child:FC<{}> = (props) => {
  return (
    <div>
      Child
    </div>
  )
}

const App = () => {
  return (
    {/**Error: Type '{ id: string; }' is not assignable to type 'IntrinsicAttributes'.**/}
    <Child id={'111'}/>
  );
}

但普通变量赋值却完全正常:

let props: {}
props = {id: '111'}

本质原因解析

核心原因在于React组件的JSX语法会被转译为createElement函数调用,而createElement的类型声明对Props做了特殊处理:

interface Attributes {
  key?: Key | null | undefined;
}

function createElement<P extends {}>(
  type: FunctionComponent<P>,
  props?: Attributes & P | null,
  ...children: ReactNode[]
): FunctionComponentElement<P>;

当定义组件:

const MyComponent = (props: {}) => <div>I am a child component</div>;

组件本身的Props类型确实是{}(任意非空值),但传入createElement后,实际校验的Props类型变为Attributes & P——即内置的Attributes接口(仅包含可选的key属性)与原P类型的交叉类型。

此时Props的有效属性被限制为仅key,因此会出现以下结果:

return (
  <div className="App">
    <MyComponent a="1" /> // 报错:额外属性'a'不被允许
    <MyComponent key="1" /> // 正常:key属于Attributes接口的合法属性
  </div>
);

内容的提问来源于stack exchange,提问作者SuCan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 00:37:38