-
Notifications
You must be signed in to change notification settings - Fork 12.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Proposal: JSX.ElementType #13890
Comments
I think this is a reasonable idea. I recall some other suggestions to this effect and it seems like this behavior is going to be relatively common among non-Reactlike frameworks. My main concern is that it seems really plausible that some framework would define |
Hi, smartclient.jsx.d.ts: declare module JSX {
export interface IntrinsicElements { }
interface Element extends isc.ICanvas { }
interface ElementClass extends Component<any, any> { }
interface HtmlElementInstance extends ElementClass { }
interface ElementAttributesProperty { __props; }
interface ElementTypeProperty { __elementType; }
} smartclient.gui.ts: (Note: all isc.* definitions are written in separate .d.ts file) namespace SmartClientJSX {
export function createElement<P extends Component<T, M>, T, M>(elementClass: {new (...args: any[]): P}, props: T, ...children: Component<any, any>[]):M {
return (<any>elementClass).create(props !== null ? props : {}, children);
}
}
abstract class Component<T, M> { private __props: T; private __elementType: M;
static create(params: any[], children) {}
}
// property 'children' will be children objects.
class Canvas extends Component<isc.ICanvasOptions, isc.ICanvas> {
static create(params, children) {
return isc.Canvas.create({
...<any>params,
children: params.children ? [...params.children, ...children] : children
});
}
}
// property 'members' will be children
class VLayout extends Component<isc.IVLayoutOptions, isc.IVLayout> {
static create(params, children) {
return isc.VLayout.create({...<any>params, members: children});
}
}
// property 'fields' will be children
class ListGrid extends Component<isc.IListGridOptions, isc.IListGrid> {
static create(params, children) {
return isc.ListGrid.create({
...<any>params,
fields: params.fields ? [...params.fields, ...children] : children
});
}
}
// no children allowed, you can see that ListGridField for ListGrid is just plain object.
class ListGridField extends Component<isc.IListGridFieldOptions, isc.IListGridField> {
static create(params) {
return {...params};
}
}
// property 'fields' will be children
// allow to pass fields in attribute "fields" and concat children as fields.
class DynamicForm extends Component<isc.IDynamicFormOptions, isc.IDynamicForm> {
static create(params, children) {
return isc.DynamicForm.create({
...<any>params,
fields: params.fields ? [...params.fields, ...children] : children
});
}
}
// FormFieldItem for DynamicForm.fields is just plain object
class FormFieldItem extends Component<isc.IDynamicFormFieldOptions, isc.IDynamicFormField> {
static create(params) {
return {...params};
}
}
// property 'tabs' is children
class TabSet extends Component<isc.ITabSetOptions, isc.ITabSet> {
static create(params, children) {
return isc.TabSet.create({...<any>params, tabs: params.tabs ? [...params.tabs, ...children] : children});
}
}
class Tab extends Component<isc.ITabOptions, isc.ITab> {
static create(params) {
return {...params};
}
} |
Hi, we are thinking to use forked version of tc internally till this feature will be released to public if this feature will be accepted in future. I know that you have more priority work, but is it possible to know how long should it take till this request will be discussed and be accepted or rejected? Thanks. |
@antanas-arvasevicius we talked about this for a while yesterday and had a bunch of questions. Is there a repo that uses this that I could look at to better understand the behavior? Otherwise I can post the Qs here |
Hi, I'll make a small public demo today by copying some of our project
files where you could test that behavior. Here is UST+02:00 timezone so I
think you'll get it tommorow. You could write some questions also or a
behavior you would expect to see in a demo.
|
Hi, Ryan, just git clone && npm install && tsc && node server.js demo will be on http://localhost:9999/ You can see that now we must explicitly cast each : Using patched compiler in PR #13891 explicit casting could be removed. Any questions are welcome. |
Hello, @RyanCavanaugh , could you please give any feedback for this issue? Are there are any plans to support this and how is it going? |
I have a lot of open questions on this with regards to how general-purpose it is. Specifically, the problem of whether the element type appears on the instance side or static side of the constructor function - there seem to be requests from people on both sides of this. The major contingents are:
My current thinking is that a long-term solution would be changing the JSX element type resolver to be similar to resolving the return type of a function. This opens up basically arbitrary possibilities (via generic type inference) but is quite a bit more complex. |
Thank you for your detailed response. Yes, seems complicated problem :) And if there is a need to have an actual type specified it could be defined as ``interface ElementTypeProperty { }` (empty interface) Is this solution doesn't cover full cases? (1, 2, 4 I think is covered, for 3 - is this question in this jsx element scope?) About some "type resolver function" and using "return type" as a result would solve all problems, but it will be difficult to "parse/execute" this during type checking? If it wouldn't the |
Great, this would solve the issue I mentioned here. #4195 (comment) |
I have a use case for a library I'm writing where I'm basically using tsx to generate DOM nodes directly (with extra sauce on top). I would like a lot to be able to specify that Couldn't the whole tsx transform simply apply the function call and type check it ? My guess is that it would also solve the whole generics issue since the type inferer works well with them -- directly calling the factory function without using tsx generally works fine... |
Hi, |
Related: #23457 |
Related: #21699 |
Related: #13260 |
Any updates on this? or #14729 |
Hello,
There are many GUI frameworks (ExtJs, SmartClient, OpenUI5) which do not works in React way and they could be easily be integrated with JSX/TSX if their JSX expressions would return correct "element type" e.g.
const listGrid = <ListGrid/> ; // should be type of ListGrid or isc.IListgrid, not JSX.Element
My proposal would be to add new special type into global
JSX
namespace -ElementTypeProperty
.JSX.ElementTypeProperty
Given an element instance type, we need to produce a type that will be return type of that JSX element. We call this the element type.
The interface JSX.ElementTypeProperty defines this process.
It may have 0 properties, in which case element instance type will be element type.
Or 1 property, in which case the element type will be the type of that property type of element instance type.
Note: Intrinsic lookup is not affected by ElementTypeProperty.
Related: #13746
The text was updated successfully, but these errors were encountered: