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

ber*_*t84 8 typescript

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

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

Run Code Online (Sandbox Code Playgroud)

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

type SignIn = (data: {email: string, password: string}) => void;
Run Code Online (Sandbox Code Playgroud)

我收到这个错误

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
Run Code Online (Sandbox Code Playgroud)

错误的完整示例在这里

有趣的是这个作品

cap*_*ian 3

你的例子可以简化为:

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

signin = record
record = signin // error
Run Code Online (Sandbox Code Playgroud)

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

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

signinArg = recordArg // error
recordArg = signinArg

Run Code Online (Sandbox Code Playgroud)

Whysignin不可分配给 ,recordsigninArg可分配给recordArg

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

有关 TypeScript 中协方差的更多信息,您可以在这里找到

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

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

在这里您可以找到非常相似的问题以及更多问题背景