打字稿功能扩展被打破
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
,则此代码无效。
为了进一步阅读,我们在这里处理的概念称为类型逆变。
打字稿 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
,则此代码无效。
为了进一步阅读,我们在这里处理的概念称为类型逆变。