以下TypeScript脚本不能与TypeScript 4.5.5或4.6.4一起使用:
class Thing {
someProperty = 42;
someMethod() {
console.log('bar')
}
}
function foo<T extends Thing>(x: T) {
let { someProperty, ...rest } = x;
rest.someMethod();
}
var t = new Thing()
t.someMethod()
foo(t)
我有两个问题:
1.在4.6.4中,错误是Property 'someMethod' does not exist on type 'Omit<T, "someProperty" | "someMethod">'.
这是由于this breaking change in TypeScript 4.6。但是,有人能解释一下什么是不可扩展的成员吗?
1.在4.5.5版本中,错误是rest.someMethod is not a function
。为什么在上述TypeScript 4.6中断更改之前出现此错误?
1条答案
按热度按时间yptwkmov1#
**简短版本:**在typescript 4.6中,讨论中的更改更多的是一个错误修复,而不是一个破坏性的更改,typescript编译器在与泛型结合使用时没有正确地键入反结构化赋值。
详细版本:
让我们来看看spread在typescript中是如何工作的,现在让我们举一个更简单的例子
我们可以看到它在4.5和4.6中编译成完全相同的javascript,你可以通过交换版本并将输出粘贴到一个diff编辑器中来确保这一点。(这也正是你提供的例子的情况)
对等的javascript代码有何作用?
我们不需要100%了解它的功能,但快速浏览一下就会发现它使用
就像
这将允许它在对象中的属性(而不是方法)上循环,我们可以在js控制台中快速检查这一点,并看到只打印了属性(而不是方法)
返回原始示例的修补版本
这个例子应该给我们同样的行为从编译器,对不对?
但事实上,它并不像typescript 4.5那样识别出rest对象上没有方法,并引发错误
您提供的示例有何不同?
这个示例直接在对象上使用反结构化,而您的示例在泛型上使用反结构化。
"虫子在哪里"
简单地说,使用泛型使得typescript在反结构化时无法检测到方法的“删除”,因此这段讨厌的代码使它通过了编译...错误仍然存在,而您在运行时看到了它,这是一个大问题,因为typescript应该在发布应用程序时提供信心(特别是类型安全)。
希望这对你有帮助