Inversify error, TypeError: Reflect.hasOwnMetadata is not a function

Inversify error, TypeError: Reflect.hasOwnMetadata is not a function

我正在一个项目中使用 inversify.js,我决定将我的数据访问 classes 作为一个单独的 NPM 包发布。

包导出一个class

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
}

在我的主要项目中使用 class 导致错误 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

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

找到解决方法,使存储库 class 非抽象并删除所有 inversify 注释。

在需要存储库 class 的 package/service 中,我有一个助手

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;

我想通了我的案子。 之前是这样的:

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";

然后工作