如何淡化TypeScript编译器?

时间:2018-08-21 21:19:56

标签: typescript

似乎TypeScript是基于Microsoft对DOM和JS的理解。如果我不在乎IE Edge,会发生什么?我在使用TypeScript时遇到问题...

例如。 Element.getBoundingClientRect()返回具有xy属性的对象-在IE和Edge以外的所有浏览器中(请参见注释here)。

所以我有compilation error TS2339: Property 'x' does not exist on type 'ClientRect | DOMRect'.

我可以说服编译器不要为此担心吗?

2 个答案:

答案 0 :(得分:3)

当TypeScript将变量的类型推断为A | B时,这实际上意味着它仅知道变量的类型为AB(或可在其中至少之一)。 因此,在访问具有这种类型的变量时,它仅允许访问两种类型都可用的属性,因为在两种情况下都存在,但可能不存在。

另一方面,类型为A & B的变量保证为类型A 和类型为B。因此,您可以在AB中找到的所有属性的并集。

在您的情况下,TypeScript实际上很友好,并且没有掩盖在某些情况下xy可能不可用的事实。但是,如果确定它们是正确的,即,如果您知道矩形是正确的DOMRect(或DOMRectReadOnly),则可以将变量强制转换为它:

const rect = elem.getBoundingClientRect() as DOMRect;

如果不太确定,名为type guards的概念可能会通过提供执行实际运行时检查的代码来支持TypeScript的类型推断,从而帮助您避免未经检查的强制转换。

if ('x' in rect) {
    // x is unique to DOMRect (ClientRect does not have it)
    // hence TS now knows rect is of type DOMRect.
    ...
}

作为参考:在Github上的Microsoft TypeScript项目上,您可以找到full DOM API types

答案 1 :(得分:2)

解决此问题的一种方法是利用interface merging.

git_remote_fetch

TypeScript将具有相同名称的两个接口合并在一起,为interface ClientRect { x: number; } let button = document.createElement('button'); button.textContent = "Say Hello"; document.body.appendChild(button); let rect = button.getBoundingClientRect(); let xCoord = rect.x; // no error! console.log(xCoord); 提供x属性。