错误化,TypeError:Reflect.hasOwnMetadata不是函数

时间:2019-03-23 16:45:25

标签: typescript inversifyjs

我在一个项目上使用inversify.js,所以我决定将数据访问类作为单独的NPM软件包提供。

包导出一个类

import { injectable, unmanaged } from 'inversify';
import { Document, Query, Model, model } from 'mongoose';
import { merge } from 'lodash';
import { BaseMongoSchema } from './schema';

export interface QueryOptions {
    conditions: any;
    projections?: any;
    populate?: [{
        path: string;
        select: string;
    }];
    archived?: boolean;
    select?: any;
    sort?: any;
    per_page?: number;
    page?: number;
}

export interface PaginationOptions {
    total: number;
    per_page: number;
    page: number;
    pages?: number;
}

export interface PaginatedResult<T> {
    pagination: {
        total: number;
        per_page: number;
        pages: number;
        page: number;
    };
    result: T[];
}

export interface IMongoRepository<T> {
    all(options: QueryOptions): Promise<PaginatedResult<T> | T[]>;
    one(id: string): Promise<T|any>;
    oneByField(field: string, value: any): Promise<T>;
    create(attributes: any): Promise<any | T>;
    delete(id: string): Promise<boolean>;
    destroy(id: string): Promise<boolean>;
    update(id: string, attributes: any): Promise<T>;
    restore(id: string): Promise<T>;
}

export class ModelNotFoundError extends Error {
    constructor(message: string) {
        super(message);
    }
}

@injectable()
export abstract class MongoRepository<T extends Document> implements IMongoRepository<T> {
    private name: string;
    private model: Model<T>;
    private schema: BaseMongoSchema;

    constructor(
        @unmanaged() name: string,
        @unmanaged() schema: BaseMongoSchema
    ) {
        this.name = name;
        this.schema = schema;
        this.model = model<T>(this.name, schema);
    }
    ...methods
}

在我的主要项目中使用该类会导致reflect-metadata出现错误

import { injectable, unmanaged } from 'inversify';
import { MongoRepository } from '@scope/data';
import { UserSchema, IUser } from '../schema/user';

@injectable()
class UserRepository extends MongoRepository<IUser> {
    constructor() {
        super(
            'UserAccount',
            UserAccountSchema
        );
    }
}

错误

if (Reflect.hasOwnMetadata(metadataKey, annotationTarget)) {
                ^
TypeError: Reflect.hasOwnMetadata is not a function

不确定是什么引发了错误,一切似乎都井然有序。任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:0)

找到一种解决方法,使存储库类成为非抽象类,并删除所有未整合的注释。

在需要存储库类的软件包/服务中,我有一个助手

import { Container } from 'inversify';
import { BaseSchema, MongoRepository } from 'some package';
import { Document } from 'mongoose';

export namespace DIHelper {
    export function registerRepository<T extends Document>(container: Container, symbol: any, name: string, schema: BaseMongoSchema) {
        container.bind(symbol)
            .toDynamicValue((_ctx) => {
                return new MongoRepository<T>(name, schema);
            })
            .inSingletonScope();
    }
}

存储库像这样绑定到容器中

import 'reflect-metadata';
import { Container } from 'inversify';
import { IUserAccount, UserAccountSchema } from '../../data/schemas/user-account';
import { IRole, RoleSchema } from '../../data/schemas/role';
import { IPolicy, PolicySchema } from '../../data/schemas/policy';
// Controllers
import '../controllers';
import { DIHelper } from '../helpers/di';
// Container
const DIContainer = new Container();
// Repository bindings
DIHelper.registerRepository<IUserAccount>(DIContainer, 'UserAccounts', 'UserAccount', UserAccountSchema);
DIHelper.registerRepository<IRole>(DIContainer, 'Roles', 'Role', RoleSchema);
DIHelper.registerRepository<IPolicy>(DIContainer, 'Policies', 'Policy', PolicySchema);
export default DIContainer;

答案 1 :(得分:0)

我弄清楚了我的案子。 之前是这样的:

import TSmalltalkData from "../../../v2/entities/module/smalltalk/SmalltalkData";
import {DeserializeError} from "../../../v2/utils/errors";
import {expect} from 'chai';
import {SMALLTALK_INPUT_ENUMS} from "../../../v2/entities/module/smalltalk/input/SmalltalkInput";
import {SmalltalkOutputTime} from "../../../v2/entities/module/smalltalk/output/time";
import {SmalltalkOutputLink} from "../../../v2/entities/module/smalltalk/output/link";
import {SmalltalkOutputText} from "../../../v2/entities/module/smalltalk/output/text";
import {factory} from "../../data_initialization";

factory是被注入的实例。 它必须放在顶部。 就像这样:

import {factory} from "../../data_initialization";
import TSmalltalkData from "../../../v2/entities/module/smalltalk/SmalltalkData";
import {DeserializeError} from "../../../v2/utils/errors";
import {expect} from 'chai';
import {SMALLTALK_INPUT_ENUMS} from "../../../v2/entities/module/smalltalk/input/SmalltalkInput";
import {SmalltalkOutputTime} from "../../../v2/entities/module/smalltalk/output/time";
import {SmalltalkOutputLink} from "../../../v2/entities/module/smalltalk/output/link";
import {SmalltalkOutputText} from "../../../v2/entities/module/smalltalk/output/text";

然后工作