为什么在TypeScript中我们可以将arguemts不兼容的函数重新分配给另一个?

时间:2017-09-25 11:00:36

标签: typescript

我用本指南https://basarat.gitbooks.io/typescript/content/docs/types/type-compatibility.html#types-of-arguments提出了这个问题。

示例代码:

/** Type Heirarchy */
interface Point2D { x: number; y: number; }
interface Point3D { x: number; y: number; z: number; }

/** Two sample functions */
let iTakePoint2D = (point: Point2D) => { /* do something */ }
let iTakePoint3D = (point: Point3D) => { /* do something */ }

iTakePoint3D = iTakePoint2D; // Okay : Reasonable
iTakePoint2D = iTakePoint3D; // Okay : WHAT

显然,iTakePoint2D的签名与iTakePoint3D不兼容。我们将它用作iTakePoint2D({ x: 100, y: 200 }),然后它会导致运行时错误,程序无法访问point.z的值。

1 个答案:

答案 0 :(得分:5)

无论好坏,TypeScript中的函数参数都是bivariant(适用于版本高达v2.5的版本)。有一个question in the TypeScript FAQ,它看起来很像你的:为什么这种类型系统没有将其作为错误捕获?

答案:强制函数参数contravariant(它们可以更广泛但不比预期类型更窄)会将此标记为错误,但也会将一些常见做法标记为错误,而它们实际上并非如此。 ;吨。要修复这些情况,需要大量的手动类型断言。基本上,为了方便,牺牲了一些正确性。 (你:"什么?!你不能这样做!"他们:"看看TypeScript Design Non-Goal #3和绝望")

还有一些关于Microsoft/TypeScript#14973中的原因的讨论,其中提到了当你开始严格执行参数逆转时出现的编译器性能问题。

但是!继续留意可能的compiler flag,它对独立函数(不是方法)强制执行此操作。不确定这是否会真正进入TypeScript 2.6或未来的某个版本,但看起来在这方面有工作要做。

希望有所帮助;祝你好运!

编辑:嗯,似乎very document you linked解释了它。 bivariance使一些好事发生(参见文档中的事件处理程序代码)和一些不好的事情(你发布的代码)。也许它没有足够的拼写?哦,好吧。