Skip to content

Instantly share code, notes, and snippets.

@gcanti
Last active March 7, 2017 15:01
Show Gist options
  • Save gcanti/7d797de57ced658dfd18777d595c77d7 to your computer and use it in GitHub Desktop.
Save gcanti/7d797de57ced658dfd18777d595c77d7 to your computer and use it in GitHub Desktop.
A hacky implementation of a default prop hoc
import * as React from 'react'
type Witness<A, B, C> = (x: A & B) => C
// P = original props
// D = defaulted props
// U = untouched props
function removeProps<P, D extends keyof P, U extends keyof P>(defaults: Pick<P, D>, witness: Witness<Pick<P, D>, Pick<P, U>, P>): (Component: React.ComponentClass<P>) => React.ComponentClass<Pick<P, U>> {
return Component => class extends React.Component<Pick<P, U>, void> {
render() {
return <Component {...this.props} {...defaults} />
}
}
}
type Props = {
name: string,
surname: string,
age: number,
// errorIfDecommented: number
}
class MyComponent extends React.Component<Props, void> {
render() {
return <div>hello {this.props.name} {this.props.surname}</div>
}
}
// the key here seems the function x => x without type annotations which forces type inference
// decommenting the errorIfDecommented prop raises an error because the constraint is violated
const MyDefaultedComponent = removeProps<Props, 'surname', 'name' | 'age'>({ surname: 'Canti' }, x => x)(MyComponent)
export default MyDefaultedComponent
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment