什么是反射 - 元数据及其目的?
使用reflect-metadata的语法和目的是什么?
有人可以提供一个例子来更好地理解它吗?
如何反射元数据有助于在typescript中实现装饰器.
将我原先存在的项目升级到Angular 4和Angular/CLI 1.0后,我收到此错误:
core.es5.js:354 Uncaught reflect-metadata shim is required when using class decorators
Run Code Online (Sandbox Code Playgroud)
我把我的项目比作新鲜的ng new
,它们在配置上看起来很相似.我重新启动了终端和计算机.删除node_modules
,npm cache clean
,npm prune
,npm i
我在Windows 7上运行
版本1.0.0上的CLI没有错误,ng build
但是当我运行应用程序时,我在浏览器中收到错误.我在https://angular-update-guide.firebaseapp.com/的帮助下从版本rc.2和Angular从v2.5升级CLI
*更新
我发现我index.scala.html
没有它的脚本标签polyfills.js
.挂起那部分之后我产生了这个错误:
Uncaught RangeError: Maximum call stack size exceeded
Run Code Online (Sandbox Code Playgroud)
的package.json
{
"name": "mikeumus",
"version": "1.0.0",
"description": "A webpack starter for angular 2",
"scripts": {
"build": "ng build -dev -e dev",
"build:aot": "ng build -prod -e prod --aot true --sourcemap false", …
Run Code Online (Sandbox Code Playgroud)正如标题中所说:reflect-metadata
API 提供了一个getMetadata
方法和一个getOwnMetadata
- 这里有什么区别?等也一样hasOwnMetadata
。
import "reflect-metadata"
function validate(target: any) {
let paramtypes = Reflect.getMetadata("design:paramtypes", target);
console.log(paramtypes); // undefined
}
@validate
class Log {
constructor(public readonly xx: string) {}
}
Run Code Online (Sandbox Code Playgroud)
打我启动服务器,打开网页发现paramtypes未定义
tsconfig.json
{
"compilerOptions": {
"target": "ESNext",
"lib": ["DOM", "DOM.Iterable", "ESNext"],
"allowJs": false,
"skipLibCheck": false,
"esModuleInterop": false,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "ESNext",
"moduleResolution": "Node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react",
"experimentalDecorators": true,
"emitDecoratorMetadata": true
},
"include": ["./src"]
}
Run Code Online (Sandbox Code Playgroud) 当函数返回类型为 时Promise<number>
,如何通过反射获得它?
如果我只是这样做
Reflect.getMetadata("design:returntype", target, key)
Run Code Online (Sandbox Code Playgroud)
它只是返回Promise
,所以有一种方法可以知道这是数字的承诺吗?
name:"Promise"
prototype:Promise {constructor: , then: , catch: , …}
reject:function reject() { … }
resolve:function resolve() { … }
Run Code Online (Sandbox Code Playgroud) 我尝试将@Reflect.metadata
装饰器应用于TypeScript类,遵循reflect-metadata.d.ts第82-84行的示例:
/// <reference path="node_modules/reflect-metadata/reflect-metadata.d.ts"/>
@Reflect.metadata('key', 0)
class C {
}
Run Code Online (Sandbox Code Playgroud)
但是,TypeScript 1.7.2编译器@Reflect.metadata
在行上生成以下错误:
错误TS1238:当作为表达式调用时,无法解析类装饰器的签名.
无法调用类型缺少调用签名的表达式.
怎么了?
我目前正在使用 Node.js 学习 TypeScript。阅读 TypeORM 时,我看到reflect-metadata
TypeORM 需要该包才能工作。需要这个包的原因是什么?
我正在使用reflect-metadata
打字稿。我编写了自己的属性装饰器,它被称为Field
. 如何获取由Field
,修饰的任何类型的字段/属性列表。例如:我想从类中获取ProductID
,ProductName
字段及其元数据Product
,如下所示/。
import 'reflect-metadata';
export const FIELD_METADATA_KEY = 'Field';
export interface FieldDecorator {
field?: string;
title?: string;
type?: string;
}
export function Field(field: FieldDecorator) {
return Reflect.metadata(FIELD_METADATA_KEY, field);
}
export class Product {
@Field({
title: 'Product Id'
})
ProductID: string;
@Field({
title: 'Product Name',
type: 'text'
})
ProductName: string;
UnitPrice: number; //not decorated
}
Run Code Online (Sandbox Code Playgroud) 我有两个装饰师.类装饰器和方法装饰器.类装饰器定义了我想在方法装饰器中访问的元数据.
ClassDecorator:
function ClassDecorator(topic?: string): ClassDecorator {
return (target) => {
Reflect.defineMetadata('topic', topic, target);
// I've also tried target.prototype instead of target
return target;
};
}
Run Code Online (Sandbox Code Playgroud)
MethodDecorator:
interface methodDecoratorOptions {
cmd: string
}
function MethodDecorator(options: decoratorOptions) {
return function (target, propertyKey: string, descriptor: PropertyDescriptor) {
// HERE IS MY PROBLEM
console.log('metaData is: ', Reflect.getMetadata('topic', target));
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的班级定义:
@ClassDecorator('auth')
export class LoginClass {
@MethodDecorator({
cmd: 'login'
})
myMethod() {
console.log('METHOD CALLED');
}
}
Run Code Online (Sandbox Code Playgroud)
问题:
MethodDecorator的以下行返回metaData is: undefined
.为什么不定义?
console.log('metaData …
Run Code Online (Sandbox Code Playgroud) 我正在使用一个属性装饰器Field
,它将它的键推送到一个fields
Reflect 元数据属性:
export function Field(): PropertyDecorator {
return (target, key) => {
const fields = Reflect.getMetadata('fields', target) || [];
if (!fields.includes(key)) {
fields.push(key)
}
Reflect.defineMetadata('fields', fields, target)
}
}
Run Code Online (Sandbox Code Playgroud)
然后我有一个抽象基类Form
,它访问 getter 附件中的元数据:
abstract class Form {
get fields() {
return Reflect.getMetadata('fields', this) || [];
}
}
Run Code Online (Sandbox Code Playgroud)
到目前为止,我已经能够成功地使用它来区分表单字段和其他类属性。考虑这些类:
abstract class UserForm extends Form {
@Field()
public firstName: string
@Field()
public lastName: string
get fullName() {
return this.firstName + ' ' + this.lastName;
}
}
class …
Run Code Online (Sandbox Code Playgroud)