1
votes

I'm trying to figure out how to write a type definition for react-highlight (class Highlightable, see here) in order to extend Highlightable and add custom functionality. Since the original Highlightable JS-class is a subclass of React.Component, I also need to have all the methods of React.Component available in my type definition. What's the best way of solving this?

This is using NPM and webpack. I'm following this tutorial.

I try to import and use the component like this:

import {Highlightable} from "highlightable";

then:

<Highlightable
enabled={true}
highlightStyle={{
...

My goal is to be able to say:

class MyHighlightable extends Highlightable { ...}

and overwrite methods. That's why I want a type definition.

I managed to get a simple Import working by adding declare module "highlightable"; to a index.d.ts file in src/@types/highlightable.

When I now try to add a class definition like this:

 declare module "highlightable" {
   export class Highlightable {
   }
}

Typescript of course complains about the missing methods from the React.Component superclass:

TS2607: JSX element class does not support attributes 
because it does not have a 'props' property.

So when extending with an empty class body export class Highlightable extends React.Component<T,T> {, in index.d.ts and adding method defintions, etc. everything compiles but I get this error at runtime:

Uncaught Error: Element type is invalid: expected a string (for 
built-in components) or a 
class/function (for composite components) but got: undefined.

Outputting the Highlightable import to console confirms it's undefined. Copy and pasting method definitions from a React type definition on Definately typed doesn't help either (still undefined).

How can I solve this and provide a type definition for a subclass? If it is not possible, how can I work around it?

1

1 Answers

0
votes

Solved, inspired by this post. My typedefinition now looks like this:

declare namespace HighlightableNs {
    class Highlightable extends React.Component<any, any> {
    }
}

declare module "highlightable" {
    export default HighlightableNs.Highlightable;
}

When subclassing, I use the default import:

import Highlightable from "highlightable";

export class HighlightableColorMarked extends Highlightable {

The custom class can now be imported normally:

import {HighlightableColorMarked} from "./wordselection/HighlightableColorMarked";

If anyone knows why this is necessary or has a more elegant solution, feel free to post.