score:1

it seems to me the material-ui definition for muithemeable function is not right ...

doing

export default muithemeable()(mainheader);

is the same as doing

export const themed = muithemeable<mainheader, {}, {}>()(mainheader)

and doesn't compile because you omitted component property type and component property state

the compiler infers

<tcomponent<p, s>,{}, {}>

which doesn't match the function constraints

        export function muithemeable<tcomponent extends (react.component<p, s>), p, s>()
            : (component: tcomponent ) => tcomponent;

... lets add the missing constrains

to satisfy the compiler , we should do

export default (props: properties) => muithemeable<mainheader, properties, any>()(new mainheader(props));

but this is giving an instance to the function , when the f is expecting a class

if you later on do ...

// ...    
import themeable from "./themeable";
let  props = { title: "hello!" };
reactdom.render(<themeable {...props}/>, document.getelementbyid("main"));

it won't work

but if you change muithemeable definition to:

 export function muithemeable<tcomponent extends (react.component<p, s>), p, s>()
        : (component: function ) => tcomponent;

then you can use:

export default muithemeable<mainheader, properties, any>()( mainheader);

the tsc will generate errors

jsx element type 'themeable' does not have any construct or call signatures

but it will transpile the right thing , and work

but that's not ok,

because:

  • it doesn't build
  • function is not describing the right parameter type
  • neither tcomponent describes what is returned,

it looks like its returning an instance when we need a class,... a type

finally:

this signature makes a bit more sense:

export function muithemeable<tcomponent extends (react.component<p, s>), p, s>(): (component: new()=> tcomponent ) => ( new() =>  tcomponent);

but after looking at the source

export function muithemeable<tcomponent extends react.component<p, s>, p extends muithemeproviderprops, s> (component: new () => tcomponent): react.statelesscomponent<p> 

and this could be a way to get away with re-writing or augmenting the definition.
wrapping the function
... and perhaps using a decorator to reduce boilerplate and easier reading...

    import * as react from "react";
    import * as reactdom from "react-dom";
    import * as injecttapeventplugin from "react-tap-event-plugin";

    // needed for ontouchtap
    // http://stackoverflow.com/a/34015469/988941
    injecttapeventplugin();


    import darkbasetheme from "material-ui/styles/basethemes/darkbasetheme";
    import muithemeprovider from "material-ui/styles/muithemeprovider";
    import getmuitheme from "material-ui/styles/getmuitheme";
    import muithemeable from "material-ui/styles/muithemeable";

    import appbar from "material-ui/appbar";
    import muithemeproviderprops = __materialui.styles.muithemeproviderprops;

    function themeable<tcomponent extends react.component<p, any>, p extends muithemeproviderprops> (component: new () => tcomponent): new() => tcomponent {
        return muithemeable<tcomponent, p, any>()(component as any) as any;
    }

    const themeable = <p, tfunction extends react.componentclass<p>>(target: tfunction): tfunction => {
        return themeable(target as any) as any;
    };

    export interface mybarprops extends __materialui.appbarprops, __materialui.styles.muithemeproviderprops {
        // ...
    }

    @themeable
    export class mybar extends react.component<mybarprops, any> {

        constructor(props?: mybarprops, context?: any) {
            super(props, context);
        }

        render() {
            if (!this.props.muitheme) {
                throw new error("muitheme not found");
            }
            return (
                <appbar {...this.props} />
            );
        }
    }

    const darktheme = getmuitheme(darkbasetheme);
    darktheme.appbar.color = "red";

    const main = () => (
        <muithemeprovider muitheme={darktheme}>
            <mybar title="my appbar" />
        </muithemeprovider>
    );

    reactdom.render(<main></main>,document.getelementbyid("root"));

Related Query

More Query from same tag