如何在 typescript tsx 代码中扩展 jsx 元素的属性?

How can I extend the attributes of jsx elements in typescript tsx code?

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 中缺少的 'erroneously')之外,我通常还想知道如何将临时属性添加到内部元素甚至我自己的元素中。奇怪的是,打字稿从不抱怨 "data-*" 属性,我也可能会切换这些属性(无论如何都想成为一个不错的 html5 开发者)。但是关于接口 HTMLAttributes 扩展的问题对我来说仍然是开放的。

它已经存在,但是有一个大写的 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 only the preact part is exported as a module so you can only augment 中看到的情况。
幸运的是,定义包含 PreactHTMLAttributes 然后由 JSX.HTMLAttributes 扩展,所以你可以这样做:

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

你需要重新定义react的ImgHTMLAttributes<T>

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)} />;