David Liu
David Liu

Reputation: 9601

Higher order class with generics in Javascript?

I'm wondering if there's a proper way to wrap a class similar to a higher order component in React Native? I've got the following:

const RecyclerViewDataWrap = <P>(Wrapee: Class<React$Component<P, *>>) => {
  return class {
    props: P

    constructor(props: P){
      this.props = props
    }
    render(){
      return (
        <Wrapee {... this.props}  />
      )
    }
  }
}

export default RecyclerViewDataWrap

// in some other component file:
export const SomeComponentData = RecyclerViewDataWrap(SomeComponent)

This allows me to create SomeComponentData objects that will render SomeComponents with the props I tell it to. However, I'd like to be able to declare the generic type along with it so that the constructor can know what types it wants. Ideally I'd like to do something like this:

type Props = {
  title?: string,
  price?: number,
}
export const SomeComponentData = RecyclerViewDataWrap<Props>(SomeComponent)

Upvotes: 2

Views: 796

Answers (1)

mvermand
mvermand

Reputation: 6117

I've got it sort of (I used class Props instead of type):

Say you have

class SomeComponent {
    constructor(public name: string) {
    }
}

and

class Props {
    title?: string;
    price?: number;
}

then you could do:

type Constructor<T> = new(...args: any[]) => T;

function RecyclerViewDataWrap<P, T extends Constructor<{}>>(Props: new ()=> P, Base: T) {

    return class extends Base {
        props: P = new Props();

        constructor(...args: any[]) {
            super(...args);
        }
    }
}

const SomeComponentData = RecyclerViewDataWrap(Props, SomeComponent);


let componentData = new SomeComponentData("My Component");
componentData.props.title = 'My title';

console.log(componentData);

I have made this mostly based on https://github.com/Microsoft/TypeScript/wiki/What%27s-new-in-TypeScript#support-for-mix-in-classes and Typescript instantiate generic object

Maybe @cartant can validate this as he seems to know a lot more of this stuff.

Upvotes: 1

Related Questions