Mar*_*emi 3 html casting typescript
我正在实施以下课程:
export class BbSVGElement extends HTMLElement implements HTMLCanvasElement { ... }
Run Code Online (Sandbox Code Playgroud)
问题是我<svg>在打字稿中找不到元素的类型:<span>元素是HTMLSpanElement,<canvas>元素是HTMLCanvasElement等等。
我问是因为要实现一个简单的任务,比如height()函数,我需要获取元素的边界框。根据这个堆栈溢出答案,这是正确的方法:
height(): number { return this.getBBox().height}
Run Code Online (Sandbox Code Playgroud)
但既然this指的是HTMLElement,当然Property 'getBBox' does not exist on type 'BbSVGElement'.ts(2339)
所以我尝试了各种铸件;像:
return (<SVGElement> this).getBBox().width
return (<SVGSVGElement> this).getBBox().width
Run Code Online (Sandbox Code Playgroud)
我当然可以做类似的事情
return (<any> this).getBBox().width
Run Code Online (Sandbox Code Playgroud)
或者
return this.offsetWidth // <-- This property here comes from HTMLElement
Run Code Online (Sandbox Code Playgroud)
但如果可能的话,我宁愿不要。
那么:正确的演员阵容应该怎么做?还是我错过了另一个选择?
<svg>TypeScript 中元素的类型是什么?
文档中<svg>元素的界面类型*.svg(即 SVG DOM)是SVGElement. <svg>HTML 文档中的元素类型(即 HTML DOM)实际上是一个无原型对象,它实现了 HTMLElement 和 SVGElement!
因此,在 TypeScript 中,您可以<svg>通过使用交集类型来表示DOM 中的元素(表示组合了两种或多种类型的所有成员的类型,而联合类型表示组合两种或多种类型的共享成员的类型) )。
像这样:
type SvgInHtml = HTMLElement & SVGElement;
const svgElement: SvgInHtml = document.createElement('svg') as SvgInHtml;
const svgHeight = svgElement.getBBox().height; // Using `SVGElement.getBBox()`.
const htmlWidth = svgElement.offsetWidth; // Using `HTMLElement.offsetWidth`
Run Code Online (Sandbox Code Playgroud)
我看到您想使用派生类来表示它- 但这是不正确的(因为类继承只允许单个父类),而是使用非封装type SvgInHtml引用,或者将其封装在对象或新类中(没有超类) ):
type SvgInHtml = HTMLElement & SVGElement;
class MySvgWrapper {
constructor( private readonly svgElement: SvgInHtml ) {
}
get height(): number {
return this.svgElement.getBBox().height;
}
}
Run Code Online (Sandbox Code Playgroud)
(这是我在正确理解您的问题之前发布的原始答案 - 我将其保留在这里并且可以访问,因为我觉得它对于发现此问题但与您的问题不同的其他人可能仍然有用):
所有(大多数?)SVG 元素的基本 SVG-DOM 接口都SVGElement 记录在 MDN 上。
假设您使用的是带有 SVG-DOM 接口的 TypeScript 3.x 或更高版本lib.dom.d.ts(请参阅我在该行下方的回答内容),那么您需要将class声明更改为:
export class MySVGElement extends SVGElement {
}
Run Code Online (Sandbox Code Playgroud)
从 TypeScript 3.x 开始,TypeScript 的 HTML DOM 类型“标准库”在 中包含 SVG DOM 接口lib/lib.dom.d.ts,因此您无需下载、导入或添加任何内容 - 直接使用SVGElement(及其派生接口)即可。
如果您lib.dom.d.ts在 GitHub 中打开当前的 TypeScript ,您可以搜索"SVGElement"(以及任何其他 SVG-DOM 接口,例如SVGGraphicsElement)并查看它在那里的声明:
例如:
/** SVG elements whose primary purpose is to directly render graphics into a group. */
interface SVGGraphicsElement extends SVGElement, SVGTests {
readonly transform: SVGAnimatedTransformList;
getBBox(options?: SVGBoundingBoxOptions): DOMRect;
getCTM(): DOMMatrix | null;
getScreenCTM(): DOMMatrix | null;
addEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGGraphicsElement, ev: SVGElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
removeEventListener<K extends keyof SVGElementEventMap>(type: K, listener: (this: SVGGraphicsElement, ev: SVGElementEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
}
Run Code Online (Sandbox Code Playgroud)
如果您遇到与未知/未定义类型相关的任何错误,请将其作为新的 StackOverflow 问题发布。