首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在TypeScript/JSX中向现有的HTML元素添加属性?

如何在TypeScript/JSX中向现有的HTML元素添加属性?
EN

Stack Overflow用户
提问于 2016-10-17 18:55:08
回答 7查看 34.5K关注 0票数 33

有人知道如何使用自定义属性正确地添加/扩展所有本机HTML元素属性吗?

有了用于合并接口的TypeScript文档,我想我可以这么做:

代码语言:javascript
运行
复制
interface HTMLElement {
    block?: BEM.Block;
    element?: BEM.Element;
    modifiers?: BEM.Modifiers;
}

<div block="foo" />; // error

但是,我在vscode 1.6.1 (最新)中得到以下Intellisense错误:

类型'HTMLProps‘上不存在ts属性’块‘。

他们所指的HTMLPropsReact.HTMLProps<T>div元素声明如下所示:

代码语言:javascript
运行
复制
namespace JSX {
    interface IntrinsicElements {
        div: React.HTMLProps<HTMLDivElement>
    }
}

我试图重新声明div,但没有结果。

相关:https://github.com/Microsoft/TypeScript/issues/11684

编辑:,这是最后为我工作的东西:

代码语言:javascript
运行
复制
declare module 'react' {
    interface HTMLAttributes<T> extends DOMAttributes<T> {
        block?: string
        element?: string
        modifiers?: Modifiers // <-- custom interface
    }
}
EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2017-02-07 09:17:04

在旧版本的类型定义文件(v0.14)中,接口只是在全局React命名空间下声明的,因此以前可以使用标准的合并语法。

代码语言:javascript
运行
复制
declare namespace React {

    interface HTMLProps<T> extends HTMLAttributes, ClassAttributes<T> {
    }
}

但是,新版本的d.ts文件(v15.0)已经声明了模块中的所有内容。由于模块不支持合并,据我所知,现在唯一的选择似乎是module augmentationhttps://www.typescriptlang.org/docs/handbook/declaration-merging.html

我做了以下实验,它对我有效:

代码语言:javascript
运行
复制
import * as React from 'react';

declare module 'react' {
     interface HTMLProps<T> {
        block?:string;
        element?:string;
        modifiers?:string;
    }

}

export const Foo = () => {

    return (
        <div block="123" element="456">
        </div>
    )
};

显然,这非常繁琐,您可以将增强代码放在另一个文件中,如打字本手册中的示例所示,然后导入它:

代码语言:javascript
运行
复制
import * as React from 'react';
import './react_augmented';

但还是很脏。因此,最好与类型定义文件的贡献者一起解决这个问题。

票数 13
EN

Stack Overflow用户

发布于 2017-07-05 15:58:58

我想使用魅力的createElement替代,这增加了一个css道具的每一个元素。

要添加到接受的答案,模块增强似乎是可行的,但HTMLProps只对非输入元素有效。正确的扩展接口似乎是HTMLAttributesSVGAttributes

代码语言:javascript
运行
复制
declare module 'react' {
  interface HTMLAttributes<T> {
    css?: any
  }

  interface SVGAttributes<T> {
    css?: any
  }
}

为了避免导入每个组件中的模块增强,重新导出createElement:

代码语言:javascript
运行
复制
// createElement.ts
import { createElement } from 'glamor/react'

declare module 'react' {
  interface HTMLAttributes<T> {
    css?: any
  }

  interface SVGAttributes<T> {
    css?: any
  }
}

export default createElement

然后告诉TS在这个tsconfig中使用我们的createElement用于JSX:

代码语言:javascript
运行
复制
{
  "compilerOptions": {
    "jsx": "react",
    "jsxFactory": "createElement"
  }
}

用法:

代码语言:javascript
运行
复制
// MyComponent.tsx
import createElement from './createElement'

export default function MyComponent() {
  return <div css={{ color: 'red' }} />
}
票数 8
EN

Stack Overflow用户

发布于 2019-05-13 09:50:06

最新的例子(2019年5月)

React定义文件(默认情况下是index.d.ts,当使用create-react-app时)包含所有标准HTML元素的列表,以及已知的属性。

为了允许自定义HTML属性,您需要定义它的类型。通过扩展HTMLAttributes接口来做到这一点:

代码语言:javascript
运行
复制
declare module 'react' {
  interface HTMLAttributes<T> extends AriaAttributes, DOMAttributes<T> {
    // extends React's HTMLAttributes
    custom?: string;
  }
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40093655

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档