How do I add attributes to existing HTML elements in TypeScript/JSX?
有人知道如何使用自定义属性正确添加/扩展所有原生 HTML 元素属性吗?
使用用于合并接口的 TypeScript 文档,我认为我可以这样做:
1 2 3 4 5 6 7 | interface HTMLElement { block?: BEM.Block; element?: BEM.Element; modifiers?: BEM.Modifiers; } ; // error |
但我在 vscode 1.6.1(最新)中收到以下 Intellisense 错误:
[ts] Property 'block' does not exist on type 'HTMLProps'.
他们所指的
1 2 3 4 5 | namespace JSX { interface IntrinsicElements { div: React.HTMLProps<HTMLDivElement> } } |
我尝试重新声明
相关:https://github.com/Microsoft/TypeScript/issues/11684
编辑:这就是最终对我有用的东西:
1 2 3 4 5 6 7 | declare module 'react' { interface HTMLAttributes< T > extends DOMAttributes< T > { block?: string element?: string modifiers?: Modifiers // <-- custom interface } } |
看起来在旧版本的类型定义文件(v0.14)中,接口只是在全局 React 命名空间下声明的,所以以前你可以使用标准的合并语法。
1 2 3 4 5 | declare namespace React { interface HTMLProps< T > extends HTMLAttributes, ClassAttributes< T > { } } |
但是新版本的 d.ts 文件 (v15.0) 已经声明了模块内的所有内容。由于模块不支持合并,据我所知,目前唯一的选择似乎是
https://www.typescriptlang.org/docs/handbook/declaration-merging.html
我做了以下实验,它对我有用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | import * as React from 'react'; declare module 'react' { interface HTMLProps< T > { block?:string; element?:string; modifiers?:string; } } export const Foo = () => { return ( ) }; |
显然这很乏味,您可以将扩充代码放在另一个文件中,如 typescript 手册中的示例所示,然后将其导入:
1 2 | import * as React from 'react'; import './react_augmented'; |
但它仍然很脏。所以也许最好解决类型定义文件的贡献者的问题。
我想使用 glamor 的 createElement 替换,它为每个元素添加一个
要添加到已接受的答案,模块扩充似乎可以解决问题,但
1 2 3 4 5 6 7 8 9 | declare module 'react' { interface HTMLAttributes< T > { css?: any } interface SVGAttributes< T > { css?: any } } |
为避免在每个组件中导入模块扩充,重新导出 createElement:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | // createElement.ts import { createElement } from 'glamor/react' declare module 'react' { interface HTMLAttributes< T > { css?: any } interface SVGAttributes< T > { css?: any } } export default createElement |
然后告诉 TS 使用我们的
1 2 3 4 5 6 | { "compilerOptions": { "jsx":"react", "jsxFactory":"createElement" } } |
用法:
1 2 3 4 5 6 | // MyComponent.tsx import createElement from './createElement' export default function MyComponent() { return } |
最新示例(2019 年 5 月)
React 类型定义文件(默认情况下 -
为了允许自定义 HTML 属性,您需要定义它的类型。
通过扩展
1 2 3 4 5 6 | declare module 'react' { interface HTMLAttributes< T > extends AriaAttributes, DOMAttributes< T > { // extends React's HTMLAttributes custom?: string; } } |
带有 TSX 的 Vue 3
1 2 3 4 5 6 7 8 9 10 | // src/index.d.ts import * as vue from 'vue'; declare module 'vue' { interface HTMLAttributes { className?: string; vHtml?: string; frameBorder?: string; } } |
从 React TypeScript Cheatsheet 添加非标准属性
1 2 3 4 5 6 7 8 | // react-unstable-attributes.d.ts import"react"; declare module"react" { interface ImgHTMLAttributes< T > extends HTMLAttributes< T > { loading?:"auto" |"eager" |"lazy"; } } |
对于 vue,以下工作:
1 2 3 4 5 6 | declare module 'vue-tsx-support/types/dom' { interface InputHTMLAttributes { autocorrect: string; autocapitalize } } |