Last active
December 27, 2018 22:31
-
-
Save maraisr/33aeb9babdb338b5faa406dee80f0978 to your computer and use it in GitHub Desktop.
Typed Higher Order Components (maybe react?)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>; | |
interface FunctionComponent<P = {}> { | |
(props: P, context?: any): string; | |
} | |
// Our component props types | |
interface IInputProps { | |
firstName: string; | |
lastName: string; | |
avatar: string; | |
} | |
interface ISubProps { | |
width: number; | |
height: number; | |
} | |
// The helper type that takes an abstract prop type, adds the downstream ISubProps + a type that's based on our IInputProps | |
type WrappedType<P extends object = {}> = P & | |
ISubProps & | |
Omit<IInputProps, 'firstName' | 'lastName'>; | |
type SubComponent<P> = FunctionComponent<WrappedType<P>>; | |
type WrappedComponent<P> = FunctionComponent<P & IInputProps>; | |
function factory<P extends object = {}>( | |
Component: SubComponent<P>, | |
): WrappedComponent<P> { | |
// The props here are of type P & IInputProps | |
return ({ lastName, firstName, avatar, ...rest }) => { | |
const restString = Object.entries(rest) | |
.map(([key, value]) => `${key}: ${value}`) | |
.join('\n'); | |
// Component's types are ISubProps + IInputProps (-firstName, -lastName) + P | |
const componentResponse = Component( | |
{ | |
avatar, | |
height: 10, | |
width: 20, | |
...rest, | |
}, | |
); | |
return `FirstName: ${firstName}\nLastName: ${lastName}\n${restString}\n\n--BEGIN--\n${componentResponse}\n--END--`; | |
}; | |
} | |
// Example impl | |
const test = factory<{ foo: string }>(props => { | |
return `hello: ${props.foo}, you have the avatar of ${ | |
props.avatar | |
} with height ${props.height} and width ${props.width}`; | |
})({ | |
firstName: 'firstName', | |
lastName: 'lastName', | |
avatar: 'avatar', | |
foo: 'foo', | |
}); | |
console.log(test); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment