Anyone know how to properly add/extend all native HTML element attributes with custom ones?
With the TypeScript documentation for merging interfaces, I thought that I could just do this:
interface HTMLElement {
block?: BEM.Block;
element?: BEM.Element;
modifiers?: BEM.Modifiers;
}
<div block="foo" />; // error
But I get the following Intellisense error in vscode 1.6.1 (latest):
[ts] Property 'block' does not exist on type 'HTMLProps'.
The HTMLProps
to which they are referring is React.HTMLProps<T>
and the div
element is declared to use it like so:
namespace JSX {
interface IntrinsicElements {
div: React.HTMLProps<HTMLDivElement>
}
}
I tried redeclaring the div
, but to no avail.
Related: https://github.com/Microsoft/TypeScript/issues/11684
Edit: Here's what ended up working for me:
declare module 'react' {
interface HTMLAttributes<T> extends DOMAttributes<T> {
block?: string
element?: string
modifiers?: Modifiers // <-- custom interface
}
}
Looks like in older versions of type definition files (v0.14) the interfaces were simply declared under a global React namespace, so previously you could use the standard merging syntax.
declare namespace React {
interface HTMLProps<T> extends HTMLAttributes, ClassAttributes<T> {
}
}
However the new version of d.ts file (v15.0) have declared everything inside a module. Since modules do not support merging, to the best of my knowledge the only option right now seems to be module augmentation
:
https://www.typescriptlang.org/docs/handbook/declaration-merging.html
I did the following experiment and it worked for me:
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>
)
};
Obviously this is quite tedious, you could put the augmentation code in another file as shown in the example from the typescript handbook, and import it:
import * as React from 'react';
import './react_augmented';
But it's still quite dirty. So maybe it's best to address the issue with the contributors of the type definition file.