Khazl
Khazl

Reputation: 125

How to extend an interface of extended class

I use the latest typescript and reactjs versions together and have a problem with extended classes and the extension of its interfaces.

For several form elements (all have the same validation methods) i have created a BaseComponent which looks like this:

/// <reference path="../typings/tsd.d.ts" />
import React = require('react');

interface P {
    id: string
    onChange: Function
    error: string
}

interface S {
    value: string
    isValid: boolean
}

class BaseComponent extends React.Component<P, S> {
    protected isValid(value) {
        //do stuff
    }
}

export default BaseComponent;

And the Component which extends from the BaseComponent:

/// <reference path="../typings/tsd.d.ts" />
import React = require('react');
import BaseComponent from './baseComponent';

interface P {
    id: string
    onChange: Function
    error: string
    required?: boolean
}

interface S {
    value: string
    isValid: boolean
    somethingNew: string
}

class NameFieldContainer extends BaseComponent {
    constructor(props: any) {
        super(props);

        this.state = {
            value: '',
            isValid: false,
            somethingNew: 'Foo'
        };

        this.aMethod();
    }

    protected aMethod() {
        this.setState({somethingNew: 'Bar'});
    }

    public render() {
        const somethingNew = this.state.somethingNew;
        return (
            <div>{somethingNew}</div>
        );
}

export default NameFieldContainer;

Now my compiler (and IDE) show some problems with the new state.somethingNew and props.required properties. I have no idea how to extends this. How can I teach the BaseComponent that he have to use the Interfaces from the NameFieldContainer?

Upvotes: 1

Views: 2412

Answers (1)

Murat Karag&#246;z
Murat Karag&#246;z

Reputation: 37624

You can use the Intersection Type to extend your existing interfaces for the props and state. Your BaseContainer would look like this

class BaseContainer<PP, SS> extends React.Component<P & PP, S & SS> {

}

and your concrete implementation of that you would use

interface PExtended {
    id: string
    onChange: Function
    error: string
    required?: boolean
}

interface SExtended {
    value: string
    isValid: boolean
    somethingNew: string
}

class NameFieldContainer extends BaseContainer<PExtended, SExtended> {...}

You also have to keep in mind if the state fields are not optional (by declaring it as value?:string) you have to set them in setState({}).

Upvotes: 2

Related Questions