すべてのネイティブHTML要素属性をカスタム属性で適切に追加/拡張する方法を知っている人はいますか?
インターフェイスをマージするためのTypeScriptドキュメント を使用して、私はこれを実行できると思いました:
interface HTMLElement {
block?: BEM.Block;
element?: BEM.Element;
modifiers?: BEM.Modifiers;
}
<div block="foo" />; // error
しかし、vscode 1.6.1(最新)で次のIntellisenseエラーが発生します。
[ts]プロパティ 'block'はタイプ 'HTMLProps'に存在しません。
彼らが参照しているHTMLProps
はReact.HTMLProps<T>
およびdiv
要素は、次のように使用するように宣言されています。
namespace JSX {
interface IntrinsicElements {
div: React.HTMLProps<HTMLDivElement>
}
}
div
を再宣言してみましたが、役に立ちませんでした。
関連: https://github.com/Microsoft/TypeScript/issues/11684
編集:これが私のために働いた結果です:
declare module 'react' {
interface HTMLAttributes<T> extends DOMAttributes<T> {
block?: string
element?: string
modifiers?: Modifiers // <-- custom interface
}
}
古いバージョンの型定義ファイル(v0.14)のように見えますが、インターフェースはグローバルReact名前空間の下で単純に宣言されていたため、以前は標準のマージ構文を使用できました。
declare namespace React {
interface HTMLProps<T> extends HTMLAttributes, ClassAttributes<T> {
}
}
ただし、新しいバージョンのd.tsファイル(v15.0)では、モジュール内のすべてが宣言されています。モジュールはマージをサポートしていないので、私の知る限り、現時点での唯一のオプションはmodule augmentation
: https://www.typescriptlang.org/docs/handbook/declaration-merging.html
私は次の実験をしました、そしてそれは私のために働きました:
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>
)
};
明らかにこれは非常に退屈な作業です。TypeScriptハンドブックの例に示すように、オーグメンテーションコードを別のファイルに入れてインポートすることができます。
import * as React from 'react';
import './react_augmented';
しかし、それはまだかなり汚れています。したがって、タイプ定義ファイルのコントリビューターで問題に対処するのが最善の方法です。
魅力的な createElement 置換を使用して、すべての要素にcss
プロップを追加したいと思いました。
受け入れられた答えに追加するために、モジュール拡張はトリックを行うようですが、HTMLProps
は非入力要素に対してのみ機能しました。拡張する正しいインターフェースはHTMLAttributes
とSVGAttributes
のようです。
declare module 'react' {
interface HTMLAttributes<T> {
css?: any
}
interface SVGAttributes<T> {
css?: any
}
}
すべてのコンポーネントでモジュール拡張をインポートしないようにするには、createElementを再エクスポートします。
// createElement.ts
import { createElement } from 'glamor/react'
declare module 'react' {
interface HTMLAttributes<T> {
css?: any
}
interface SVGAttributes<T> {
css?: any
}
}
export default createElement
次に、このtsconfigでJSXにcreateElement
を使用するようTSに指示します。
{
"compilerOptions": {
"jsx": "react",
"jsxFactory": "createElement"
}
}
使用法:
// MyComponent.tsx
import createElement from './createElement'
export default function MyComponent() {
return <div css={{ color: 'red' }} />
}
最新の例(2019年5月)
Reactタイプ定義ファイル(デフォルト-index.d.ts
create-react-app
)すべての標準HTML要素と既知の属性のリストが含まれています。
カスタムHTML属性を許可するには、そのタイプを定義する必要があります。 HTMLAttributes
インターフェースを拡張することでそれを行います:
declare module 'react' {
interface HTMLAttributes<T> extends AriaAttributes, DOMAttributes<T> {
// extends React's HTMLAttributes
custom?: string;
}
}
Vueの場合、次のように機能します。
declare module 'vue-tsx-support/types/dom' {
interface InputHTMLAttributes {
autocorrect: string;
autocapitalize
}
}