-
Notifications
You must be signed in to change notification settings - Fork 11
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: Can I use this inside a property decorator? #7
Comments
Hello @Eluminati, I play around with tst-reflect and decorators in this repo: https://github.com/Hookyns/react-typed-di I've made this repl with example usage of class decorators. PS: This code is responsible for decorators handling: |
OK, I've tryed to play around a litle bit with the package. For some reason I can't get any type information. Here is what I#ve done: // I am using ts-config-paths-plugin
import CommonExample from "~common/models/Example";
import { Model } from "~client/utils/decorators";
@Model()
export default class Example extends CommonExample {
}
// decorators.ts
/**
* @reflectDecorator
*/
export function Model<T extends BaseModel>(): ClassDecorator {
const theType = getType<T>();
console.log(theType);
return (target) => {
const schemaDefinition = Reflect.getMetadata("schemaDefinition", target.prototype);
console.log(schemaDefinition);
};
}
// This is just for completenes... uninteresting in this case
export function Attr<T extends BaseModel>(options: Pick<SchemaTypeOptions<keyof T> & ThisType<T>, allowedAttrFields> = {}): PropertyDecorator {
// TODO:
// 1. Make immutable on readonly
// 2. Make enum on union types? Or maybe build own custom validator
// 3. Make required if not optional
// 4. Determine "ref" in case of Model
// 5. Determine "of" in case of Map
return (target, attributeName) => {
let schemaDefinition = Reflect.getMetadata("schemaDefinition", target);
if (!schemaDefinition) {
schemaDefinition = {};
Reflect.defineMetadata("schemaDefinition", schemaDefinition, target);
}
if (schemaDefinition[attributeName]) throw new Error(`Attribute "${attributeName.toString()}" is already defined`);
schemaDefinition[attributeName] = options;
};
} I am building my app with @ionic/vue. This is my vue.config.js module.exports = {
//...
chainWebpack: (config) => {
config.module.rule('ts').use('ts-loader').merge({
options: {
configFile: TSCONFIG_PATH,
compiler: "ttypescript"
}
});
}
} I added the folloging to my compilerOptions in tsconfig.json: "plugins": [
{
"transform": "tst-reflect-transformer"
}
] because I am using config extension, I have added the "reflection" field in the corresponding tsconfig.json. Otherwise the transformer can't find that field. I configured If you want to see the whole example, you can clone the repo: https://github.com/Eluminati/boilerplate then: npm install |
@Eluminati There are several issues I've noticed. Output of But the main problem is visible by running I'll update runtime and transformer packages and test it in your project,.. Maybe there are more unknown types like this. |
@Eluminati I've made few updates and build of whole project is now OK. JavaScript code generated by running Please, download the latest versions of both packages - runtime and transformer. But while running /* harmony import */ var tst_reflect__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! tst-reflect */ "./node_modules/tst-reflect/reflect.js");
/**
* @reflectDecorator
*/
function Model(__genericParams__) {
const theType = (0,tst_reflect__WEBPACK_IMPORTED_MODULE_1__.getType)(); // <<<============ wrong; there should be __genericParams__.T Correct code generated by Typescript, before bundling: import { getType } from "tst-reflect";
/**
* @reflectDecorator
*/
export function Model(__genericParams__) {
const theType = (__genericParams__ && __genericParams__.T); // <<<========== __genericParams__.T is used
console.log(theType);
return (target) => {
const schemaDefinition = Reflect.getMetadata("schemaDefinition", target.prototype);
console.log(schemaDefinition);
};
} BTW: dist/js/index.js does not even contain generated metadata... |
hey thank you very much. Maybe the generated code is incomplete because of the "transpileOnly" configuration of ts-loader? |
Yeap, it can be a hundred different things,.. |
### Added - `getType(val: any)` it is possible to get type of runtime value, <dl> <dd> ```typescript const someValue: unknown = new Animal(); getType(someValue); // > Type<Animal> ``` This works mainly with classes. Before #29 is implemented, `@reflect()` decorator, `@reflect` JSDoc tag or `getType<OfThatType>()` is required or there will be no Type metadata. Native types such as Object `{ foo: "", bar: 5 }`, Array `[ {}, true, 5 ]` and primitive types are supported too; those types are recognized and their properties are parsed at runtime. *Getters and setter of Objects are recognized.* \ *Classes without metadata will be parsed as Objects.* </dd> </dl> - `Decorator.getArguments(): Array<any>` - constant literal arguments of decorators are captured, - `Type.isPrimitive()`, - partial test coverage (~75%) - issue #28, - `TypeBuilder`, - decorator can be CallExpression`@decorator()` or (new) just Identifier `@decorator` - implementation of #7 - custom Property and Method decorators supporting `getType<T>()` of generic parameters, like already supported class decorators. ### Changed - JSDoc tags @reflectGeneric and @reflectDecorator removed in favor of single @reflect, - `Property.decorators` changed to `Property.getDecorators()` - to keep it same as `Type.getDecorators()` and `Method.getDecorators()`, - `Type.flattenInheritedMembers()` support base union and intersection types, - fixed issue #27, - fix of some circular dependencies in runtime package, - few other small bug fixes.
@Eluminati property decorators are working in new version, same as method decorators. |
Available from:
Version details in CHANGELOG |
Hi there,
first of all this seems to be a very interesting project and maybe it's ver useful.
I wonder if I could use this in property decorators to get the type during runtime. I am planing to build a Mongoose Schema definition based on the class I am writing. For this I think I need to do something like this:
Do you think this could work? I am still in preparation of my project so I can't test it yet.
What I want to avoid is something like this:
The text was updated successfully, but these errors were encountered: