Open LennyLixalot opened 7 years ago
Can you provide some example code so I can verify I'm understanding what you're saying?
Basically you want JSX.ElementClass
, except for the constructor function type typeof X
in the expression <X />
in addition to the current checking which checks the instance type X
?
Yes, exactly that.
Unless we've misunderstood something fundamental about how this whole JSX thing is working (we're .NET devs a little out of our comfort-zones, it's possible), the createElement function is called with typeof X
as the first argument, and in order to really do anything useful with it we need to create an instance of X
. If we could control the syntax of the constructor we would be able to do this in a reliable and type-safe manner.
For our particular use-case we'd probably want something like
type ComponentConstructor<TProps> = new (props: TProps) => Component<TProps>
or maybe
type ComponentConstructor<TComponent extends Component<TProps>, TProps> = new (props: TProps) => TComponent
Slightly simplified example of course.
Note the plan would be to have our base-class implement this constructor and assign the props as required, so in most cases the component classes wouldn't even need to do anything with constructors at all, but if they did they'd be forced to comply.
Seems reasonable to think about. We didn't implement anything like this earlier simply because React components almost never override their base class constructor, thus there's little chance for error.
If we could get this and #13618 (setting limits on children) then this feature would feel much more complete and applicable to a larger-range of DSL-use-cases.
BTW, Mithril needs this for TS users to be able to use anything besides classes for components if they use JSX. And we have a lot of components that aren't - a lot of people prefer either object or closure components, and even our docs don't just use class components.
This is basically a blocker for us to support JSX in TS in any real capacity, if that helps explain a good use case for adding this feature.
For us, something as simple as type ElementType<P> = ...
would work. (We can't use an interface, since we need a union here.) The return type is just the name of a valid component type for a factory.
BTW, we do support JSX in JS, so TS is the odd one out here. Just thought I'd clarify.
@RyanCavanaugh Do you have any status update on this? I know it's a bit of an old bug.
We're writing a non-react library that uses TS's JSX support with custom interfaces defined in the JSX namespace. Unless we are very much mistaken (The documentation seems a little out-of-date in this area? Most of our current understanding comes from reading through issues on here, we may have missed something.) it seems that while ElementClass can be used to define the type of the element instance type there is no interface to limit the members of the element class type.
We have a custom component base-class and an equivalent to React's createElement function. Our createElement function needs to be able to create instances of the component classes. To be able to do this in a type-safe manner, we need to be able to specify an interface for the element class type that can require a specific constructor signature.
This feels like an oversight in the current implementation TBH. With React itself it's even possible to create components with incompatible constructors that would fail at runtime.