You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Allow extracting meta data from typescript components #719
We would like to use dash-generate-components on some Typescript components to allow our Python developers to use them in their Dash code. We have a custom pipeline to transpile the Typescript components to a bundle but we're currently blocked by this line of code:
Would you support the addition of .ts and .tsx files to this filter. This would allow us to continue using Typescript.
Example typescript code
Dev.jsx
(Currently I am saving this as Dev.jsx to allow the extracting of metadata.)
importReactfrom'react';typeProps={/** * my description of what a label is */label?: string,};exportdefaultclassTestextendsReact.Component<Props>{render(){const{label}=this.props;return<h1>{label}</h1>;}}
Test.py
# AUTO GENERATED FILE - DO NOT EDITfromdash.development.base_componentimportComponent, _explicitize_argsclassTest(Component):
"""A Test component.Keyword arguments:- label (string; optional): my description of what a label is"""@_explicitize_argsdef__init__(self, label=Component.UNDEFINED, **kwargs):
self._prop_names= ['label']
self._type='Test'self._namespace='something'self._valid_wildcard_attributes= []
self.available_properties= ['label']
self.available_wildcard_properties= []
_explicit_args=kwargs.pop('_explicit_args')
_locals=locals()
_locals.update(kwargs) # For wildcard attrsargs= {k: _locals[k] forkin_explicit_argsifk!='children'}
forkin []:
ifknotinargs:
raiseTypeError(
'Required argument `'+k+'` was not specified.')
super(Test, self).__init__(**args)
Good idea! @Marc-Andre-Rivet do you see any blockers to allowing this? We already support flow, I can imagine us running into problems with complex types but presumably as long as people stay within reason we should be able to handle it.
This has been on my radar for a while and been looking at the available options periodically. Last time I've tried this the types were not pulled correctly past a certain complexity and was having trouble with imported types. Being based on the Babel AST, some information was getting lost along the way. @andrenanninga is pointing to a different implementation/solution than what I tried. Would need testing but if it works I'm 100% for it. If this works fine with the table, I'd argue it will probably be fine with anything we can throw at it.
the old limitation still exists: all type definitions related to the props must be in the same file
react-docgen is only aware of babel configurations (not webpack), which means the babel.config.js needs to include the typescript preset -- nothing complicated here, just some annoying technicalities based on project structure (tried this out in the table)
prop types only defined in TS will not be debuggable with the new Dash DevTools as no typing information will survive for runtime (This project was attempting to bridge that gap but now seems inactive) -- @alexcjohnson presumably a pure flowjs interface would suffer from the same limitations
Simply adding tsx and ts is not enough as the dash component generator has dependencies on the metadata's structure -- end result is an incorrectly populated docstring and prop list for the generated py component wrapper
A partial solution that works to solve both the TS typing needs and the runtime prop types needs is using PropTypes.InferPropsexample which will take a propTypes structure and spew out a TS interface. I haven't tested this in depth but it did seem to behave as expected / provide correct typing enforcement when I played around with it in the table.
All in all, there are definite upsides to improve direct TS support but want to make it clear that a component developer will lose access to some Dash features (DevTools) in doing so. The duck-typing nature of TS does not make this something we can fix later.
Is there any progress here ?. We have some typescript React components that we'll like to use in dash. I'm currently publishing my typescript components, and then wrapping them in plain JS components.
@chabb I last had a look at this in ~November, support was still not quite there but there is progress being made. I haven't had the time to look since. The DataTable suffers from the same situation you describe above, having to duplicate the PropTypes into TypeScript types. I'll try and have another look at this in the next couple of weeks. Better TS support would allow significant 🔪🌴🐫 in our codebase too.
Due to this, another feature this issue could potentially enable (in Dash 2+ when Python 2.7 support is dropped) is to generate type annotated Dash (Python) components based on the TypeScript type definitions.
Advantages:
The JavaScript/React developer can easily, using his/her TypeScript language, potentially automatically communicate the object/types the component assumes to the Python user. It could also further improve auto-generated Dash docs of components (easier keeping them in sync and understandable for Python programmers since they start becoming used to type annotations from typing in the standard library).
Python users writing Dash apps could potentially get immediate feedback from their editor (e.g. VS Code), or using mypy in CI settings, notifying when input arguments to components are of wrong type and/or have wrong nested structure.
This might not be the case, but maybe it could enable future improvements in JSON encoding performance (e.g. isinstance() in Python is relatively costly runtime wise AFAIK, so a naïve JSON encoding function of some large listwithout type annotation information should in theory I guess be more costly than a list given to an input argument with type annotation List[int] for example).
Activity
alexcjohnson commentedon May 15, 2019
Good idea! @Marc-Andre-Rivet do you see any blockers to allowing this? We already support flow, I can imagine us running into problems with complex types but presumably as long as people stay within reason we should be able to handle it.
Marc-Andre-Rivet commentedon May 15, 2019
This has been on my radar for a while and been looking at the available options periodically. Last time I've tried this the types were not pulled correctly past a certain complexity and was having trouble with imported types. Being based on the Babel AST, some information was getting lost along the way. @andrenanninga is pointing to a different implementation/solution than what I tried. Would need testing but if it works I'm 100% for it. If this works fine with the table, I'd argue it will probably be fine with anything we can throw at it.
Marc-Andre-Rivet commentedon May 15, 2019
I'll put this on the tech roadmap for tracking.
Marc-Andre-Rivet commentedon May 23, 2019
Looking at this:
babel.config.jsneeds to include the typescript preset -- nothing complicated here, just some annoying technicalities based on project structure (tried this out in the table)tsxandtsis not enough as the dash component generator has dependencies on the metadata's structure -- end result is an incorrectly populated docstring and prop list for the generated py component wrapperA partial solution that works to solve both the TS typing needs and the runtime prop types needs is using
PropTypes.InferPropsexample which will take a propTypes structure and spew out a TS interface. I haven't tested this in depth but it did seem to behave as expected / provide correct typing enforcement when I played around with it in the table.All in all, there are definite upsides to improve direct TS support but want to make it clear that a component developer will lose access to some Dash features (DevTools) in doing so. The duck-typing nature of TS does not make this something we can fix later.
chabb commentedon Jan 17, 2020
Is there any progress here ?. We have some typescript React components that we'll like to use in dash. I'm currently publishing my typescript components, and then wrapping them in plain JS components.
Marc-Andre-Rivet commentedon May 11, 2020
@chabb I last had a look at this in ~November, support was still not quite there but there is progress being made. I haven't had the time to look since. The DataTable suffers from the same situation you describe above, having to duplicate the PropTypes into TypeScript types. I'll try and have another look at this in the next couple of weeks. Better TS support would allow significant 🔪🌴🐫 in our codebase too.
anders-kiaer commentedon May 19, 2021
Since type annotations in Python 3+ have taken inspiration from TypeScript, there is some isomorphism between the two.
Due to this, another feature this issue could potentially enable (in Dash 2+ when Python 2.7 support is dropped) is to generate type annotated Dash (Python) components based on the TypeScript type definitions.
Advantages:
typingin the standard library).mypyin CI settings, notifying when input arguments to components are of wrong type and/or have wrong nested structure.isinstance()in Python is relatively costly runtime wise AFAIK, so a naïve JSON encoding function of some largelistwithout type annotation information should in theory I guess be more costly than alistgiven to an input argument with type annotationList[int]for example).frnhr commentedon May 13, 2022
Just wanted to link this here, seem like serious progress is being made on this front! 🥳
#1956
alexcjohnson commentedon Jan 24, 2024
Looks like we forgot to close this with #1956 😄