-
Notifications
You must be signed in to change notification settings - Fork 8
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
Output TypeScript typedefs #11
Comments
(continued from https://github.com/JasonKleban/Framework7.d.ts/issues/31#issuecomment-414347635) @nolimits4web - great! I glanced over the source. I have some questions. In Phenome.js, are you planning to write out typescript source for each of vue, react, and web component outputs and then have the .d.ts extracted automatically during a tsc/vue build? Or are you planning on having additional Do you have an outline of the desired generated definitions for each? Like, an idea of the structure of the generated .d.ts; or .tsx, .ts.vue, and ... whatever web components' type safety is supposed to look like? If not, I think there's a bit of an art to structuring it. My new v3 branch has some ideas (especially in framework7-react) (not sure of them though) on declaration merging that might allow Phenome.js to make a single pass down each component, grouping all component-level and app-level changes together by the component that adds them. Since I haven't gotten very far, you may be able to forsee also the different facets of generation that need to be supported. So far I have seen app-level and component-level params/props, methods, events, and maybe even static methods? What else does it need templates for? Could you start a compiler of .d.ts files within Phenome.js source that merely lists out the components? I'm currently of the opinion that react is much more typesafe friendly (and, in fairness, that typescript is more react-friendly) compared to vue, so I'd suggest starting with /lib/compilers/react/jsx-transformer/typedefs.js (?). The code in, eg, lib/compilers/react/jsx-transformer/index.js is a little dense for me as an outsider (which is why I push typescript 💁). Could you maybe comment it more? Or heavily comment the new skeletal typedefs.js? |
Hey @JasonKleban First of all, we need to abstract from Framework7 :). Here we only compile/generate components. And i think we need the thing that will generate Phenome manipulates with AST in format generated by acorn. Under the hood it takes original component declaration object and continuously modifies and transforms it for final output. Each Vue/React compilers are separate. First stage is JSX transformer which transforms JSX to render function, like babel's JSX transform but better 😈 , next stage is component transformer that modifies object and transforms it to class like in case of React. With ts generation i think it should be easier as we don't need to modify original object. We need to walk through original object, for example: export default {
name: 'my-component',
props: {
foo: Boolean,
bar: String,
},
...
methods: {
open() {
this.dispatchEvent('open', el);
...
},
close() {
...
},
},
} Then using AST walk we need to collect (as you mentioned) props, methods and events and generate the string that will be saved to namespace MyComponent {
export interface Props {
// Props
foo?: boolean
bar?: string
// Events
onOpen?: (el : HTMLElement) => void
}
}
export class MyComponent extends React.Component<MyComponent.Props, {}> {
// Methods
open(animate: true) : void
close(animate: true) : void
} So yes, i think we need additional const dtsTemplate = `
namespace {{name}} {
export interface Props {
{{props}}
{{events}}
}
}
export class {{name}} extends React.Component<{{name}}.Props, {}> {
{{methods}}
} And based on collected data from AST walk, just to fill it. If you want, i will try to setup React' ts-transformer file and stick it to component logic with basic template so it should be easier for you to dig in and test the output. But i'm not too good in TS and maybe wrong in some points here :) Also we need to hear an input from @bencompton |
Ok, just pushed dts branch where i set up initial typescript definitions generator https://github.com/phenomejs/phenome/blob/dts/lib/compilers/react/typescript-generator/index.js It doesn't save to file yet, but at least it is good for initial testing where you can see generated output (in console). I also already added methods to collect component props, methods and events into usual arrays so they can be easier processed to fill the dts template |
I've been meaning to start working on this issue pretty soon. Looks like you guys have a great start on it! @nolimits4web - gathering the props, methods, and events is looking good! Another feature I had planned TypeScript support for slots. For the components generated by Phenome, that would be easy--just add |
Guys, I pushed final bits to dts branch, now it:
So far, looks good. At least VSCode correctly suggests component props during writing, so I guess it is working right :) I would like you to check/test it and if all is good we can do the release. Yes, and all this for React only. I couldn’t find good or correct example of ts definition for Vue components so maybe need your help with it |
This can be extremely useful, but not sure it is possible :) |
@nolimits4web - looking good! This covers props, methods, events, and slots on the Phenome components themselves, and I can't really think of anything else at the moment. I was initially thinking that we would have to do something to allow slots on non-Phenome components in React (i.e., React HTML elements), but it turns out that @types/react already has slots covered: interface HTMLAttributes<T> extends DOMAttributes<T> {
...
// Standard HTML Attributes
accessKey?: string;
className?: string;
contentEditable?: boolean;
contextMenu?: string;
dir?: string;
draggable?: boolean;
hidden?: boolean;
id?: string;
lang?: string;
placeholder?: string;
slot?: string;
... Once F7 is generating type definitions, that should be the best test. As for Vue, that situation is more complicated like you said. React typings is a great feature for now! Nice work! |
The only thing I saw was that method return types aren't getting generated and are being left as unknown. Ideally, they would be typed as either void or whatever the actual return type is, but I don't think it is really worth the trouble. In React, it is frowned upon to call methods from outside of a component anyhow, so hopefully nobody will be calling methods on components very often. |
Yes, the methods deserve the correct type. If it's not in the Phenome model, perhaps the model can be extended? Unless they are ALWAYS
This is a little dangerous - imagine that renderedProps included documentation from the original Phenome model that included the literal phrase Perhaps something like a single |
Along with PropTypes could there be a |
Guys, just merged dts branch to master and did the release. Made few code tweaks mentioned by @JasonKleban . Also added few bits of awesomeness and it will look for object if it specified as object spreed in props, like we have with Mixins in F7. It even correctly reads it if it was imported from other file like mixins.js. So F7-React definitions have all props in place. @JasonKleban I’m not sure how to realize ts props override because comments are not parsed by AST so we can’t see them. The only thing I made is if prop type is type of Class (starts from Uppercase) then it will be left as is |
What version of TypeScript is this targeting? Getting a bunch of compilation errors using TypeScript 3.0.1. |
I committed some fixes (in the above pull requests) to get this to compile. I have one project that's running on it. What's missing:
|
@ariofrio thanks for fixes you sent, great job 👍 Good point, i was also thinking about ability to add some extra output to generated TS declarations. So i just pushed 0.1.5 release of Phenome with support such extras using comments in phenome component. 3 types of extras are supported:
|
Pushed F7 fix here framework7io/framework7@bee4ba5 |
No description provided.
The text was updated successfully, but these errors were encountered: