【问题标题】:How can I extend the attributes of jsx elements in typescript tsx code?如何在 typescript tsx 代码中扩展 jsx 元素的属性?
【发布时间】:2018-07-05 03:36:45
【问题描述】:

test.tsx

<img onerror="this.style.display='none'" height="178" cmd="start" />

产量

error TS2339: Property 'onerror' does not exist on type 'HTMLAttributes'.

所以我在 JSX 部分上方的 test.tsx 中添加:

namespace JSX {
  interface HTMLAttributes {
    onerror?: any; // 1. attempt: add the missing onerror attribute
  }
  interface IntrinsicElements {
    img: any // 2. attempt: generally override the type of img, allowing anything
  }
}

但是没有效果。嗯?

如何在本地向我要使用的 JSX 代码添加属性?

我知道我可以粗暴地破解导入的类型文件,但我想知道是否有本地方法。

编辑: 除了 onerror 属性(即 preact.d.ts 中“错误地”缺失)之外,我通常想知道如何将临时属性添加到内在元素甚至我自己的元素。奇怪的是,打字稿从不抱怨“data-*”属性,我也可能会切换(无论如何都想成为一个不错的 html5 开发人员)。但是关于扩展接口 HTMLAttributes 的问题还是悬而未决。

【问题讨论】:

  • 顺便说一句,如果你不给某人加标签或评论他的回答,那么他将不会收到通知。

标签: typescript jsx preact tsx


【解决方案1】:

它已经存在,但带有大写字母 E,如 definition file 所示。

但这对您没有帮助,因为(据我所知)您不能只在其中放一个字符串并期望对其进行评估。
事实上编译器会抱怨说:

Type '{ onError: "this.style.display='none'"; height: "178"; }' is not assignable to type 'DetailedHTMLProps<ImgHTMLAttributes<HTMLImageElement>, HTMLImageElement>'.
  Type '{ onError: "this.style.display='none'"; height: "178"; }' is not assignable to type 'ImgHTMLAttributes<HTMLImageElement>'.
    Types of property 'onError' are incompatible.
      Type '"this.style.display='none'"' is not assignable to type '(event: SyntheticEvent<HTMLImageElement>) => void'.

相反,您需要执行以下操作:

class MyComponent {
    private img: HTMLImageElement;

    render() {
        return <img height="178" onError={ this.onError.bind(this) } ref={ el => this.img = el } />;
    }

    private onError() {
        this.img.style.display = "none";
    }
}

编辑

根据我在definition file for preact 中看到的内容,只有preact 部分被导出为模块,因此您只能使用augment
幸运的是,定义包含 PreactHTMLAttributes,然后由 JSX.HTMLAttributes 扩展,因此您可以这样做:

declare module "preact" {
    interface PreactHTMLAttributes {
        onerror?: any;
    }
}

【讨论】:

  • 感谢您的输入。我在它丢失的地方使用 preact.d.ts。所以无论如何都应该在那里添加这个,会这样做。那么,你是对的,这是一个事件,所以应该像一个事件一样处理。我的问题集中在“onerror”上,但我也有其他 expando 属性。我仍然想知道如何添加。我将扩展我的问题。也许你对此也有想法。
  • 检查我修改后的答案
  • 太棒了!这就是我想了解的。必须更新自己有关名称空间和模块的信息。非常感谢。
【解决方案2】:

你需要重新定义 react 的ImgHTMLAttributes&lt;T&gt;

import * as React from 'react'
declare module 'react' {
    interface ImgHTMLAttributes<T>  {
         onError?: ReactEventHandler<T>;
    }
}

或者更好的是在DOMAttributes上重新定义它:

import * as React from 'react'
declare module 'react' {
    interface DOMAttributes<T> {
        onError?: ReactEventHandler<T>;
    }
}

编辑

问题是关于 preact,因为它使用命名空间,我们需要一些三斜杠来使事情正常工作:

react.ext.d.ts

/// <reference path="./node_modules/preact/dist/preact.d.ts" />
declare namespace JSX {
    interface HTMLAttributes {
        onError: JSX.GenericEventHandler;
    }
}

test.tsx

/// <reference path="./node_modules/preact/dist/preact.d.ts" />
/// <reference path="react.ext.d.ts" />
import * as React from 'preact'
let x = <img height="178" onError={o => console.log(o)} />;

【讨论】:

  • 谢谢。将 preact 与略有不同的 preact.d.ts 一起使用。 HTMLAttributes 位于命名空间 preact 之外的 JSX 命名空间中。围绕您的建议尝试了所有方法,但没有成功。
猜你喜欢
  • 2019-05-18
  • 2019-06-20
  • 2020-02-22
  • 2017-02-26
  • 2017-05-06
  • 2019-12-23
  • 2015-10-31
  • 2021-03-24
  • 2021-12-26
相关资源
最近更新 更多