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

时间:2018-01-25 19:27:07

标签: typescript jsx preact tsx

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中错误地&#39;缺失)之外,我通常想知道如何将ad-hoc属性添加到内部甚至我自己的元素。打字原声奇怪而且几乎没有人会抱怨数据 - *&#34;我可能会切换的属性(无论如何都想成为一个不错的html5 dev)。但是关于HTMLAttributes接口扩展的问题仍然对我开放。

2 个答案:

答案 0 :(得分:3)

您需要重新定义反应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)} />;

答案 1 :(得分:2)

它已经存在,但有一个大写字母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;
    }
}