Skip to content
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

[Question] getType returns either Invalid (using getType<Type>()) or unkonwn (using getType(var)) #93

Open
zerobytes opened this issue Sep 19, 2024 · 7 comments
Labels
question Further information is requested

Comments

@zerobytes
Copy link

zerobytes commented Sep 19, 2024

I recently installed rttist in my typescript library.
It's a very simple model library, where everything is just typescript classes and enums.

the generated metadata looks good.

the library is installed in a react application, where rttist is also installed

In the react app, I am calling getType, that is exported from the library through the metadata.typelib located in the library
Library index.ts

export * from './metadata.typelib'

React App

import { getType, Metadata } from 'library-root-name'

The issue is, when I log getType it is either "Invalid Invalid [::invalid::Invalid]" or "Unknown unknown [#unknown]".

console.log(getType<ClassFromLibrary>().displayName) // Outputs Invalid Invalid [::invalid::Invalid]
const instance = new ClassFromLibrary();
console.log(getType(instance ).displayName) // Outputs Unknown unknown [#unknown]

For reference, ids are respectively "::invalid::Invalid" and "#unknown"


If I log Metadata.getModules(), all the library modules are correctly there.
If I log Metadata.getTypes(), all the library types are correctly there.


1- I ran rttist init in the library
2- I ran rttist generate in the library
3- I moved the metadata.typelib to src
4- I exported all exports from metadata.typelib in my index.ts
5- I installed rttist in the react app
6- I imported the getType and Metadata that are being exported from the library
7- getType does not work as expected

@zerobytes zerobytes added the question Further information is requested label Sep 19, 2024
@Hookyns
Copy link
Owner

Hookyns commented Sep 19, 2024

You can use getType() function only when you setup transformer.

ad3) It should not be required. It should be generated into the project root folder; based on tsconfig.
ad 4) Generated metadata.typelib.ts file is for the library project itself. Do not export it.
ad 6) You have to generate metadata also in the React app and use it's metadata.typelib.ts.
When you generate the metadata in the react project, there should be one extra import here:
image
There should be import of the library's public.typelib.js file from dist folder (or folder you configured).
Check out this page in docs.

EDIT: But the main problem, in my opinion, is with the transformer. The rttist init does not configure transformers. The way you made the metadata work is clever, and it seems to work that way, but it's not how it should be done.

@Hookyns
Copy link
Owner

Hookyns commented Sep 22, 2024

@zerobytes If you prepare some repro, I can help you to configure it.

@zerobytes
Copy link
Author

zerobytes commented Sep 23, 2024

hey @Hookyns
Thanks for your reply.
Ok, I'll setup a transformer. However, considering that its a react application, do I need to eject in order to do it? I would rather not do that, if possible. And which transformer should I apply? webpack?
About moving metadata.typelib to src:
According to here , getType should be imported from metadata.typelib, in order to have access to internal types. However, metadata.typelib imports the types as if they're based in the same root. (not to mention that in not ejected apps, you cant import from outside src)
e.g.
src/file.ts
in metadata.typelib, it will be imported as import("./file.ts")
App will not build. Even if there is some automagic that adds the metadata.typelib to dist, which would "make it work" after built, the app itself wouldn't build.
Or am I missing something?

@zerobytes
Copy link
Author

Updated tsconfig with baseUrl and imports on metadata.typelib seem correct now

@zerobytes
Copy link
Author

Ok.
So, the current state is, as far as I understand, if I have a create react app that is not ejected, I will hardly be able to make it work.
There is a restriction that prevents me from importing from outside src (ModuleScopePlugin) so I can't import metadata.typelib within the app without ejecting.

I wonder if it is really necessary that metadata.typelib remains on root instead of at the src folder.
plus, creact react app uses webpack, which doesn't have a transformer yet. Is this true?

Overall, this project really interests me, as there is absolutely nothing as good as this (in terms of features) available and I have been a framework creator since the early 2000's, and reflection is a must.

I am currently creating a component that will create a form based on a model, with any nesting complexity.
This is already possible with the workaround I did (exporting the metadata.typelib from the data model lib, moving to src, etc...) However, I still see some issues and would certainly benefit from staying out of workarounds to be able to get updates.

That said, I would like to collaborate on the project if you're open to it.

@Hookyns
Copy link
Owner

Hookyns commented Sep 23, 2024

This is quite complex topic. I got the flu so I am not capable to cover everything right now and I'm responding from a phone.

Main points:

  • Generated metadata TS file in src is there just to allow you dynamically import modules. It has to be part of the source code so bundlers transform those import paths. You don't really need this metadata TS file for anything else. The most important file is public.typelib.js generated into dist folder. It exports the Metadata library with getTypes() and getModules() functions. You can wrap it on your own. You can also set the "importers" on your own.
    We have "ionic-solidjs" project where I use RTTIST as a cmd tool; I use just the JS typelib. (I work on standalone RTTIST typegen API, so cmd tool authors can use it. Still WIP)

  • getType() function requires transformer because getType() does nothing. It is replaced by Metadata.resolve("identifier of the type used as argument of geType").

So you have to configure transformer in projects where you want to use getType function. If it will be only in the library, then you don't have to configure it in the React app. Well.. it's also required if you want to use the feature with runtime generic types - eg. your lib exports something like

export function getForm<TModel>() {
    return generateForType(getType<TModel>());
}

, your users also have to configure transformer. So in such case the eject will be required.

Webpack is supported by current tst-reflect package (this repository; RTTIST is in custom repository - it's closed alpha) but I wouldn't use it for new tools like you are creating. RTTIST transformer is written in Rust. It is TS to TS transformer so it is possible to use it as webpack loader. You can create webpack loader plugin. 🙂 Webpack has low prio for me because everybody use Vite etc. these days.

Note:
The whole idea behind generated JS typelibs... Each project should generate its own typelib (MetadataLibrary type in TypeScript) that contains types from the project itself and types imported from typelibs of dependencies. If my project has dependency on eg. lib-a package, and it has reflection section in its package.json, its typelib is imported and included in generated typelib of my project. So my Metadata.getTypes() returns all my types and all types from dependencies.

I will post some examples when I get to PC. I can also invite you to RTTIST repo.

@Hookyns
Copy link
Owner

Hookyns commented Sep 25, 2024

EDIT: It is possible without eject.
There is the Craco that allows you to tweak the CRA configuration without ejecting.

I'm preparing demo.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants