为啥 Record<string, any> 可以等于函数?

Posted

技术标签:

【中文标题】为啥 Record<string, any> 可以等于函数?【英文标题】:Why can Record<string, any> equal Functions?为什么 Record<string, any> 可以等于函数? 【发布时间】:2022-01-20 14:23:59 【问题描述】:

我一直在测试各种类型的打字稿,直到遇到以下情况。

为什么Record&lt;string, any&gt; 可以等于函数?

type C =  [key: string]: any  // Record<string, any>;
const C0: C = undefined // error
const C1: C = null // error
const C2: C = 2 // error
const C3: C = 'hello world' // error
const C4: C =  foo: 'bar'  // ok
const C5: C = () => undefined // ok

但是Records&lt;string, unknown&gt; 不能?

type B =  [key: string]: unknown  // Record<string, unknown>;
const B0: B = undefined // error
const B1: B = null // error
const B2: B = 2 // error
const B3: B = 'hello world' // error
const B4: B =  foo: 'bar'  // ok
const B5: B = () => undefined // error

Typescript playground

【问题讨论】:

【参考方案1】:

Record&lt;string, any&gt; 是可分配性的特殊情况,它基本上意味着任何对象类型。这在this GitHub issue中有解释

如果目标类型有,通常源类型必须有一个索引签名,但是对于 :any 这实际上没有任何暗示(根据定义,每个属性都必须匹配 any),所以我们将 [s: string]: any a出于可分配性的原因,无操作。这启用了一些以前不起作用的模式:

function doSomething(obj:  [s: string]: any) 
  // ...


const obj =  a: 1, b: 2 ;
// WAS ERROR: 'obj' lacks index signature
doSomething(obj);

这在某些情况下会产生一些不良的可分配性,因此我们没有将此规则应用于 : unknown 以便您可以选择您想要的行为。

【讨论】:

我不明白。你是说Function 是对象吗?还是你暗示Record&lt;string, any&gt; = any @SILENT 是的,函数是对象。所有函数签名都扩展 Function 扩展 Object typescriptlang.org/play#code/…

以上是关于为啥 Record<string, any> 可以等于函数?的主要内容,如果未能解决你的问题,请参考以下文章

为啥隐式展开的可选选项不在 [String : Any] 类型的字典中展开

无法将空对象设置为 Record 类型的参数的默认值

对象字面量的 TS 接口

Typescript 通用消息工厂

我有一个 map<string, vector<record>>,如何从 vector<record> 中删除记录?

将 [Dictionary<String,Any?>] 转换为 [Dictionary<String,Any!>] ?迅速 3