问题描述
问题 在 typescript 中,如果您想使用已经具有 DOM 属性的 DOM 元素,您应该如何声明这些属性以指定 Typescript 应该允许它们?
示例
像由 DOM 定义的 ondragstart
和 draggable
背景
我使用 Typescript 编写的 Stimulus 进行了一些拖放操作。我的实现在浏览器中工作,而且 Rails webpacker 在开发模式下似乎没有抱怨 (Rails 6.0.3
),但是当它编译资产 (be rake assets:precompile
) 时,我得到了这些打字稿错误。
请记住,我是 Typescript 的新手。
我认为问题在于 Typescript 不知道某些东西是 HTML5 拖放的 DOM 实现所固有的(例如属性 draggable
、ondragstart
等)。而在我的 event
中,它不喜欢 dropEffect
。也许 event
(即 Event
)的类型应该是 Event
我在这里做错了什么?任何帮助将不胜感激。
[tsl] ERROR in /Users/jason/Work/xyz/app/javascript/controllers/audience/movable_pip_controller.ts(31,18)
TS2339: Property 'draggable' does not exist on type 'Element'.
ERROR in /Users/jason/Work/xyz/app/javascript/controllers/audience/movable_pip_controller.ts
./app/javascript/controllers/audience/movable_pip_controller.ts
[tsl] ERROR in /Users/jason/Work/xyz/app/javascript/controllers/audience/movable_pip_controller.ts(32,18)
TS2339: Property 'ondragstart' does not exist on type 'Element'.
这两个都作为原生 HTML5 属性存在,但我想只在支持 HTML5 的浏览器上?也许我这里的 babel 设置太严格了?
'elemenet' 来自 Stimulus
我想告诉 Typescript 我知道这些都是原生 DOM 元素上的属性并允许它们
ERROR in /Users/jason/Work/xyz/app/javascript/controllers/audience/movable_pip_controller.ts
./app/javascript/controllers/audience/movable_pip_controller.ts
[tsl] ERROR in /Users/jason/Work/xyz/app/javascript/controllers/audience/movable_pip_controller.ts(40,5)
TS2322: Type 'void' is not assignable to type '(this: GlobalEventHandlers,ev: DragEvent) => any'.
ERROR in /Users/jason/Work/xyz/app/javascript/controllers/audience/movable_pip_controller.ts
./app/javascript/controllers/audience/movable_pip_controller.ts
[tsl] ERROR in /Users/jason/Work/xyz/app/javascript/controllers/audience/movable_pip_controller.ts(41,ev: DragEvent) => any'.
不知道为什么我会得到这个。
ERROR in /Users/jason/Work/xyz/app/javascript/controllers/audience/movable_pip_controller.ts
./app/javascript/controllers/audience/movable_pip_controller.ts
[tsl] ERROR in /Users/jason/Work/xyz/app/javascript/controllers/audience/movable_pip_controller.ts(42,ev: DragEvent) => any'.
ERROR in /Users/jason/Work/xyz/app/javascript/controllers/audience/movable_pip_controller.ts
./app/javascript/controllers/audience/movable_pip_controller.ts
[tsl] ERROR in /Users/jason/Work/xyz/app/javascript/controllers/audience/movable_pip_controller.ts(43,ev: DragEvent) => any'.
掉落效果
ERROR in /Users/jason/Work/xyz/app/javascript/controllers/audience/movable_pip_controller.ts
./app/javascript/controllers/audience/movable_pip_controller.ts
[tsl] ERROR in /Users/jason/Work/xyz/app/javascript/controllers/audience/movable_pip_controller.ts(50,11)
TS2339: Property 'dropEffect' does not exist on type 'Event'.
我的代码(用刺激编写,通过 Rails 6 中的 webpacker 编译)
import { Controller } from "stimulus";
import { polyfill } from "mobile-drag-drop";
// optional import of scroll behavIoUr
import { scrollBehavIoUrDragImageTranslateOverride } from "mobile-drag-drop/scroll-behavIoUr";
// options are optional ;)
polyfill({
// use this to make use of the scroll behavIoUr
dragImageTranslateOverride: scrollBehavIoUrDragImageTranslateOverride,});
export default class MovablePipController extends Controller {
static targets = [
"pipComponent","topLeft","topRight","bottomLeft","bottomright",];
private pipComponentTarget!: HTMLCanvasElement;
private topLeftTarget!: HTMLElement;
connect(): void {
this.element.classList.add("bottom-right");
this.element.draggable = true;
this.element.ondragstart = this.onDragStart.bind(this);
this.topLeftTarget.ondragenter = () => this.movePipTo("top-left");
// prevent default is need to avoid interface glitches in touch envs
this.topLeftTarget.ondragover = event.preventDefault();
this.topRightTarget.ondragover = event.preventDefault();
this.bottomLeftTarget.ondragover = event.preventDefault();
this.bottomrightTarget.ondragover = event.preventDefault();
// move pip to bottom-right upon load
this.pipComponentTarget.dataset.corner = "bottom-right";
}
onDragStart(event: Event): void {
event.dropEffect = "none";
}
movePipTo(corner: string): void {
this.pipComponentTarget.dataset.corner = corner;
}
}
解决方法
答案: 使用 Stimulus 目标明确定义父对象的类型。
connect(): void {
this.element.draggable = true;
...
变成
static targets = [
"pipComponent",];
connect(): void {
this.pipComponentTarget.draggable = true;