Skip to content

Instantly share code, notes, and snippets.

@ncochard
Created August 20, 2018 09:04
Show Gist options
  • Save ncochard/c1dd4c6d76f2830227d97b709926525f to your computer and use it in GitHub Desktop.
Save ncochard/c1dd4c6d76f2830227d97b709926525f to your computer and use it in GitHub Desktop.
Annotations are not compiled by TypeScript correctly.
import {Component, Fragment} from "react";
import * as React from "react";
import { MySimpleComponentA } from "./my-componentA";
// import { MySimpleComponentB } from "./my-componentB";
import { MySimpleComponentC } from "./my-componentC";
export class MyApp extends Component {
public render() {
return <Fragment>
<MySimpleComponentA lastName="Cochard" /> {/*DOES NOT COMPILE*/}
<MySimpleComponentA lastName="Cochard" firstName="Nicolas" /> {/*COMPILES, but I should not have to specify the first name.*/}
{/*<MySimpleComponentB lastName="Cochard" />*/}
<MySimpleComponentC lastName="Cochard" /> {/*COMPILE*/}
</Fragment>;
}
}
import {Component, ComponentClass} from "react";
import * as React from "react";
import { myDecorator } from "./my-decorator";
export interface IInjectedProps {
firstName: string;
}
export interface IProvidedProps {
lastName: string;
}
@myDecorator<IInjectedProps, IProvidedProps>({ firstName: "Nicolas" })
export class MySimpleComponentA extends Component<IInjectedProps & IProvidedProps> {
public render() {
return <span>{this.props.firstName} {this.props.lastName}</span>;
}
}
import {Component, ComponentClass} from "react";
import * as React from "react";
import { myDecorator } from "./my-decorator";
import { myHoc } from "./my-hoc";
export interface IInjectedProps {
firstName: string;
}
export interface IProvidedProps {
lastName: string;
}
@myHoc<IInjectedProps, IProvidedProps>({ firstName: "Nicolas" }) // DOES NOT COMPILE
export class MySimpleComponentB extends Component<IInjectedProps & IProvidedProps> {
public render() {
return <span>{this.props.firstName} {this.props.lastName}</span>;
}
}
import {Component, ComponentClass} from "react";
import * as React from "react";
import { myHoc } from "./my-hoc";
export interface IInjectedProps {
firstName: string;
}
export interface IProvidedProps {
lastName: string;
}
class MySimpleComponentInternal extends Component<IInjectedProps & IProvidedProps> {
public render() {
return <span>{this.props.firstName} {this.props.lastName}</span>;
}
}
export const MySimpleComponentC = myHoc<IInjectedProps, IProvidedProps>({firstName: "Nicolas"})(MySimpleComponentInternal);
import {Component, ComponentClass} from "react";
import * as React from "react";
import { myHoc } from "./my-hoc";
export function myDecorator<TInjectedProps, TProvidedProps>(injected: TInjectedProps): ((Target: ComponentClass<TProvidedProps>) => any) {
return myHoc<TInjectedProps, TProvidedProps>(injected);
}
// export const myDecorator = myHoc;
import {Component, ComponentClass} from "react";
import * as React from "react";
export function myHoc<TInjectedProps, TProvidedProps>(injected: TInjectedProps)/*: ((Target: ComponentClass<TInjectedProps & TProvidedProps>) => ComponentClass<TProvidedProps>)*/ {
return function Wrapper(Target: ComponentClass<TInjectedProps & TProvidedProps>)/*: ComponentClass<TProvidedProps>*/ {
const DecoratedComponent = class extends Component<TProvidedProps> {
public static displayName: string;
public render() {
const provided = this.props as TProvidedProps;
return <Target {...provided} {...injected} />;
}
};
DecoratedComponent.displayName = `WithSearchContext(${getDisplayName(Target)})`;
return DecoratedComponent /*as ComponentClass<TProvidedProps>*/;
};
}
function getDisplayName(WrappedComponent: ComponentClass<any>) {
return WrappedComponent.displayName || WrappedComponent.name || "Component";
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment