Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extending base class property in Typescript

I'm trying to create a wrapper class for ReactReduxForm's Control component to add additional functionality. Here is the base class/component definition:

export class Control<T> extends React.Component<ControlProps<T>, {}> {
    static custom: React.ComponentClass<ControlProps<HTMLInputElement>>;
    static input: React.ComponentClass<ControlProps<HTMLInputElement>>;
    static text: React.ComponentClass<ControlProps<HTMLInputElement>>;
    static textarea: React.ComponentClass<ControlProps<HTMLTextAreaElement>>;
    static radio: React.ComponentClass<ControlProps<HTMLInputElement>>;
    static checkbox: React.ComponentClass<ControlProps<HTMLInputElement>>;
    static file: React.ComponentClass<ControlProps<HTMLInputElement>>;
    static select: React.ComponentClass<ControlProps<HTMLSelectElement>>;
    static reset: React.ComponentClass<ControlProps<HTMLButtonElement>>;
    static button: React.ComponentClass<ControlProps<HTMLButtonElement>>;
}

I would like to override onKeyPress functionality for all types of controls (eg. input, text, textarea, etc.) which are static properties of the base Control class/component.

Here is my skeleton definition for my derived class:

import * as React from "react";
import { Control } from "react-redux-form";

export class CustomControl<T> extends Control<T> { }

I would like the following functionality to apply to all control types (eg. text, select, etc.) of CustomControl:

  onKeyPress(e: any) {
    if (e.key === "Enter") {
      e.preventDefault();
    }
  }

How can I have my `onKeyPress() functionality be used?

like image 482
im1dermike Avatar asked Jan 23 '18 17:01

im1dermike


People also ask

How do I extend a class in TypeScript?

Just like object-oriented languages such as Java and C#, TypeScript classes can be extended to create new classes with inheritance, using the keyword extends . In the above example, the Employee class extends the Person class using extends keyword.

Can an interface extend a class TypeScript?

In TypeScript, interfaces can also extend classes, but only in a way that involves inheritance. When an interface extends a class, the interface includes all class members (public and private), but without the class' implementations.

What is extends keyword in TypeScript?

The extends keyword is used to create a child class of another class (parent). The child class inherits all the methods from another class. Inheritance is useful for code reusability: reuse properties and methods of an existing class when you create a new class.

How do I add a property in TypeScript?

To add a property to an object in TypeScript, set the property as optional on the interface you assign to the object using a question mark. You can then add the property at a later point in time without getting a type error. Copied!


1 Answers

Instead of extending Control with CustomControl you should wrap it.

What you are really looking to do is modify the render() method of Control and add in a custom onKeyPress. The problem with extending Control is that you can only override Control's render method and not make changes to pieces of it.

However, if you wrap the Control component with your own component, you are able to influence it in the way you are looking to.

If you look at the definition for ControlProps<T> you will see this:

export interface ControlProps<T> extends React.HTMLProps<T> {

Because it is extending React.HTMLProps it supports the onKeyPress method as a prop.

If we combine all this information together, you can do something like:

import * as React from "react";
import { Control, ControlProps } from "react-redux-form";

export class CustomControl<T> extends React.Component<ControlProps<T>> {

    onKeyPress(e: any) {
        if (e.key === "Enter") {
            e.preventDefault();
        }
    }

    render() {
        return <Control {...this.props} onKeyPress={e => this.onKeyPress(e)} />;
    }
}

Please note that the above implementation will completely override any onKeyPress passed as a prop to CustomControl in favor of your custom onKeyPress.

If you also wanted to call any onKeyPress that gets passed as a prop you could add the following to the bottom of your custom onKeyPress function:

// After custom logic call any onKeyPress passed to this
this.props.onKeyPress && this.props.onKeyPress(e);
like image 87
casieber Avatar answered Sep 26 '22 17:09

casieber