为什么类型“Record”不接受具有已定义键的对象作为值

2024-03-31

我试图在类型中拥有一个可以接受任何对象作为输入的函数。我把它定义为

type Props = { onSubmit: (data: Record<string, unknown>) => void};

但是当我尝试将这种类型传递给它时

type SignIn = (data: {email: string, password: string}) => void;

我收到这个错误

Type 'SignIn' is not assignable to type '(data: Record<string, unknown>) => void'.
  Types of parameters 'data' and 'data' are incompatible.
    Type 'Record<string, unknown>' is missing the following properties from type '{ email: string; password: string; }': email, password

错误的完整示例是here https://www.typescriptlang.org/play?#code/C4TwDgpgBAyglgcwHYEklQLxQBQBMCGw+AXFAN4QC2+cANqQM7ABOcSCANFGPgwwO4B7ZrkYs2CAL4BKTAD4oAN0FxcAbgBQAY0FImUBolRJS8ZGkw4K1Olx58hImfPJQdewbQgA6WoITYVDS0drwCwriykpoaoJBQAArMgmAMlmRQujAArgBGlHDApHiEJFAAShA6IgA8TKzsXNlIANZIgvxIcrIYCsqq0dq6+ll5BUWJyanpo-mFjEZo0UA

Funny 这有效 https://www.typescriptlang.org/play?#code/PTAuE8AcFMAIGUCWBzAdgSVbAvLAFACYCGoRAXLAN7QC2RiANhQM6gBOiqyANLJEc2YB3APZsCLdp2QBfAJQ4AfLABuIxAQDcAKBABjEalaxmKDKgpI0mHPmp1GvfoNHj5SqrANGRDaADoGEWQ8WnoGJwFhMQIFGR1tCBhYAAU2EUhmW0pYQ3gAVwAjGkRQCkISclgAJWgDcQAeVg4uXnzUAGtUESFURQVsZTUNeO1vYzyikrLU9MzsyeLS8vtwyJcY90HPcd8AoJCwxz4o11jYGXigA


你的例子可以简化为:

declare var signin: (data: { email: string, password: string }) => void
declare var record: (data: Record<string, unknown>) => void

signin = record
record = signin // error

如果您检查参数的可分配性,这会更有趣。您将看到可分配性被颠倒了。

declare var signinArg: { email: string, password: string }
declare var recordArg: Record<string, unknown>

signinArg = recordArg // error
recordArg = signinArg

Why signin不可分配给record but signinArg可分配给recordArg.

答案是: 打字稿中的函数与其参数是逆变的。这是设计使然。

您可以找到有关 TypeScript 中协方差的更多信息here https://stackoverflow.com/questions/66410115/difference-between-variance-covaraince-contravariance-and-bivariance-in-typesc

尝试禁用strictFunctionTypes编译器标志。您会看到错误消失了。

以前,所有函数都是双变的,而且不安全。

Here https://stackoverflow.com/questions/68681526/why-cant-a-generic-member-function-in-a-class-implementing-an-interface-take-an/68682276#68682276您可以找到非常相似的问题以及更多问题背景

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么类型“Record”不接受具有已定义键的对象作为值 的相关文章

随机推荐