在 typescript 中,如果您想使用 DOM 元素,您应该如何声明这些属性以指定 Typescript 应该允许它们?

问题描述

问题 在 typescript 中,如果您想使用已经具有 DOM 属性的 DOM 元素,您应该如何声明这些属性以指定 Typescript 应该允许它们?

示例 像由 DOM 定义的 ondragstartdraggable

背景

我使用 Typescript 编写的 Stimulus 进行了一些拖放操作。我的实现在浏览器中工作,而且 Rails webpacker 在开发模式下似乎没有抱怨 (Rails 6.0.3),但是当它编译资产 (be rake assets:precompile) 时,我得到了这些打字稿错误

请记住,我是 Typescript 的新手。

我认为问题在于 Typescript 不知道某些东西是 HTML5 拖放的 DOM 实现所固有的(例如属性 draggableondragstart 等)。而在我的 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;

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...