似乎TypeScript
是基于Microsoft对DOM和JS的理解。如果我不在乎IE Edge,会发生什么?我在使用TypeScript时遇到问题...
例如。 Element.getBoundingClientRect()
返回具有x
和y
属性的对象-在IE和Edge以外的所有浏览器中(请参见注释here)。
所以我有compilation error TS2339: Property 'x' does not exist on type 'ClientRect | DOMRect'.
我可以说服编译器不要为此担心吗?
答案 0 :(得分:3)
当TypeScript将变量的类型推断为A | B
时,这实际上意味着它仅知道变量的类型为A
或B
(或可在其中至少之一)。
因此,在访问具有这种类型的变量时,它仅允许访问两种类型都可用的属性,因为在两种情况下都存在,但可能不存在。
另一方面,类型为A & B
的变量保证为类型A
和类型为B
的。因此,您可以在A
和B
中找到的所有属性的并集。
在您的情况下,TypeScript实际上很友好,并且没有掩盖在某些情况下x
和y
可能不可用的事实。但是,如果确定它们是正确的,即,如果您知道矩形是正确的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属性。