-
-
Save fbartho/3973337d702e5d10b255d24f28d4f596 to your computer and use it in GitHub Desktop.
Test that demonstrates the new Generic Propagation features available in TypeScript 3.4
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
import React from "react"; | |
interface InjectedProps { | |
injected1: string; | |
} | |
interface PubProps<Foo> { | |
pubProp1: Foo; | |
} | |
declare function bind<T>( | |
component: React.ComponentType<T & InjectedProps>, | |
): React.ComponentType<T>; | |
declare class A<B> extends React.Component<PubProps<B> & InjectedProps> {} | |
const APrimeComponent = bind(A); // No good :( | |
// type inferred to: React.ComponentType<PubProps<unknown>> | |
declare function AFunc<B>( | |
props: PubProps<B> & InjectedProps, | |
): React.ReactElement; | |
const AFuncPrimeComponent = bind(AFunc); // No good :( | |
// type inferred to: React.ComponentType<PubProps<unknown>> | |
declare function bindHack<T>( | |
component: (props: T & InjectedProps) => React.ReactElement, | |
): (props: T) => React.ReactElement; | |
const AFuncPrimeComponentHack = bindHack(AFunc); | |
// type inferred correctly! AFuncPrimeComponentHack is generic | |
const render = () => <AFuncPrimeComponentHack pubProp1={5} />; | |
/// -------------------------------------------------------------------- | |
interface PartialBinder<SomeOtherType> { | |
bind1: <T>( | |
component: (props: T & SomeOtherType) => React.ReactElement, | |
) => (props: T) => React.ReactElement; | |
bind2: <T>( | |
component: React.FunctionComponent<T & SomeOtherType>, | |
) => React.FunctionComponent<T>; | |
bind3: <T>( | |
component: React.ComponentType<T & SomeOtherType>, | |
) => React.ComponentType<T>; | |
} | |
interface DynamicInjectedProps { | |
meep: boolean; | |
} | |
declare class BComponent<C> extends React.Component< | |
PubProps<C> & DynamicInjectedProps | |
> {} | |
declare const BFuncComponent: <C>( | |
props: PubProps<C> & DynamicInjectedProps, | |
) => React.ReactElement; | |
declare const helper: PartialBinder<DynamicInjectedProps>; | |
const B1PrimeComponent = helper.bind1(BComponent); // Doesn't work -- error! | |
const B1FuncPrimeComponent = helper.bind1(BFuncComponent); // Yay! Success! | |
const B2PrimeComponent = helper.bind2(BComponent); // Doesn't work -- error! | |
const B2FuncPrimeComponent = helper.bind2(BFuncComponent); // type inferred to: React.ComponentType<PubProps<unknown>> | |
const B3PrimeComponent = helper.bind3(BComponent); // type inferred to: React.ComponentType<PubProps<unknown>> | |
const B3FuncPrimeComponent = helper.bind3(BFuncComponent); // type inferred to: React.ComponentType<PubProps<unknown>> | |
// Summary: Actual, bare, Function components are required for correct inference! | |
// React.FunctionComponent or React.ComponentType do *not* work! |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment