打字稿功能扩展被打破

Typescript function extension is broken

打字稿 3.9.4:

type Test = ((value: { a: number }) => any) extends ((value: { [key: string]: any }) => any) ? true : false;

测试的预期类型为真,因为 {a: number} 确实 extends {[key: string]: any}

Test 的实际类型是 false,我不太明白。有什么方法可以让这种情况发挥作用吗?

这种类型不扩展另一种。

我们可以看到 { a: number } 确实 扩展 { [key: string]: number } 通过想象调用一个带有这样签名的函数:

foo(arg: { [key: string]: number })

提供 { a: number } 类型的参数是有效的。 foo 对它的参数所做的任何事情对于 { a: number } 类型的事情也是有效的。

但是如果你有:

foo(arg: (value: { [key: string]: number }) => any)

提供 (value: { a: number }) => any 类型的参数是无效的,因为 foo 的参数需要一个能够接受具有任何字符串键的对象的函数。想象一下,如果 foo 是这样实现的:

foo(arg: (value: { [key: string]: number }) => any) {
  arg({ b: 7 });
}

如果 arg 的类型为 (value: { a: number }) => any,则此代码无效。

为了进一步阅读,我们在这里处理的概念称为类型逆变