I have a function type StatelessFunctionComponent (aka SFC) that I use as an annotation like so:
import * as React from 'react';
import { SFC } from 'react';
// Imported types look like:
// import { ReactNode, ReactElement } from 'react';
// type SFC<P> = (props: P & { children?: ReactNode }, context?: any) => ReactElement<any> | null
type Props = {};
const MyComponent: SFC<Props> = props => <div>Hello, World!</div>
I would like to pass a generic into this function type via the annotation. However, that does not appear to be possible.
Pseudo-code:
import * as React from 'react';
type Props<T> = { t: T };
// How can we make this function receive a generic that is passed into
// the function type annotation?
const MyComponent: <T> SFC<Props<T>> = props =>
<div>Hello, World!</div>
Is there any existing or suggested syntax that could support this?
One workaround is to avoid the type annotation altogether, and instead just write the function signature out manually:
import * as React from 'react';
import { ReactElement } from 'react';
type Props<T> = { t: T };
// Since we have no way of passing the generic into the function type annotation,
// we have to write out the full function type
const MyComponent = <T>(props: Props<T>): ReactElement<any> | null =>
<div>Hello, World!</div>
Another workaround is to use a createSubType helper:
import * as React from 'react';
import { SFC } from 'react';
const createSubType = <T extends any>() => <SubType extends T>(
subType: SubType,
) => subType;
const createGenericSFC = createSubType<SFC<any>>();
type Props<T> = { t: T };
const MyComponent = createGenericSFC(<T extends any>(props: Props<T>) => (
<div>Hello, World!</div>
));
It's not exactly clear what you're trying to do here - can you make these examples self-contained and provide more context on expected behavior?
@RyanCavanaugh I've tried to improve the original description. They are self-contained examples but they do rely on the React typings. However, I have provided an inline definition of the SFC type, which should make them self-contained.)
@RyanCavanaugh Any updates on this?
I'm not sure if this is exactly what you mean, but it does something similar:
type SFC<T> = (argNotProps: T) => Element;
function doSomething<T>(arg: T): Element {
return null as any;
}
type Props<T> = { props: T };
type Remake<F> = F extends SFC<infer T2> ? SFC<Props<T2>> : never;
const j: Remake<typeof doSomething> = null as any;
j({ props: undefined });
@RyanCavanaugh There is a style of writing type annotations that prefers to write a single type (eg, on a const), rather than explicitly type all of the parameters of the function that the const contextually types. This request seems to be for the ability to create unbound type parameters independently of signatures or type aliases (the only two places we can currently introduce them) to facilitate specifying an unbound generic on the LHS of an assignment and letting the generic flow into the correct locations on the RHS.
Hit the nail on the head @weswigham
This issue has been marked as 'Question' and has seen no recent activity. It has been automatically closed for house-keeping purposes. If you're still waiting on a response, questions are usually better suited to stackoverflow.
This issue has been marked as 'Question' and has seen no recent activity. It has been automatically closed for house-keeping purposes. If you're still waiting on a response, questions are usually better suited to stackoverflow.
As per https://github.com/microsoft/TypeScript/issues/27124#issuecomment-456980444, can we re-open this and mark it as a suggestion? /cc @RyanCavanaugh @weswigham
Another example: we have a HOC function type which we want to use as an annotation on a const. However we can't because the HOC is generic:
type HOC<P, P2> = (
ComposedComponent: ComponentType<P>,
) => ComponentType<P2>;
// Ideally we could somehow re-use the `HOC` function type:
// declare const myHoc: <P, P2> HOC<P, P2>
// But we can't, so we have to write out the whole of the `HOC` type, but inline in the function:
declare const myHoc: <P, P2>(
ComposedComponent: ComponentType<P>,
) => ComponentType<P2>;
@OliverJAsh if you really think the feature would be useful, you should probably open an issue with some kind of basic proposal for what new syntax/behavior we'd need to support.
Most helpful comment
@RyanCavanaugh There is a style of writing type annotations that prefers to write a single type (eg, on a
const), rather than explicitly type all of the parameters of the function that theconstcontextually types. This request seems to be for the ability to create unbound type parameters independently of signatures or type aliases (the only two places we can currently introduce them) to facilitate specifying an unbound generic on the LHS of an assignment and letting the generic flow into the correct locations on the RHS.