我在 React TypeScript Cheatsheet 网站上看到了以下观点:“空接口、{} 和 Object 都代表“任何非空值”,而不是您可能认为的“空对象”。”
例如:
let value: {};
value = 1;
value = "foo";
value = () => alert("foo");
value = {};
value = { foo: "bar" };
value = undefined; // Error Type
value = null; // Error Type
上面的示例表明,当类型为 {} 时,可以匹配字符串、函数和任何非空值。
所以,如下面的代码所示,当我将 Child 组件的类型定义为 FC<{}> 时,我的 props 类型变成了 {},这似乎意味着:“你可以将字符串、函数和任何非空值传递为给孩子的道具。”
但是,当我在父组件中使用 Child 组件并尝试将 Child 的 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'}
我想得到一个基本的解释。
当您使用
FC<{}>
定义 React 组件时,您是在说该组件根本不接受任何 props。这是因为 {}
被解释为 props 对象不能包含任何键。所以 {}
意味着没有钥匙。
类型
{}
表示props对象是一个空对象。当您尝试传递 { id: '111' }
时,TypeScript 会引发错误,因为 id
不是 {}
允许的键,因为 {}
应该根本没有键!
如果您希望
Child
组件接受任何道具,请按以下步骤操作:
const Child: FC<Record<string, unknown>> = (props) => {
return (
<div>
Child
</div>
);
}
Record<string, unknown>
是一种 TypeScript 实用程序类型,表示具有任何类型的字符串键和值的对象。相当于{ [key: string]: unknown }
。 unknown
指定值可以是任何类型,但它们的确切类型在编译时未知。
或者如果您希望孩子接受
id
作为道具:
const Child: FC<{ id: string }> = ({ id }) => {
return (
<div>
Child with ID: {id}
</div>
);
}
注意事项:
引自博客:
逆变是一种规则,强制函数的输入类型 必须是其所在函数的输入类型的超类型 分配给
由于 TypeScript 的上述属性:
下面的代码编译时会出现错误:
type EmptyObject = {};
type Func = (f : EmptyObject) => void;
const func : Func = ({ id }) => {
console.log({id})
};
并且这个可以正常工作:
type IdObject = { id : string}
type Func2 = (f : IdObject) => void;
const func2 : Func2 = ({}) => {
};
这正是您在上面看到的行为。