首页 > 解决方案 > 反转错误,TypeError: Reflect.hasOwnMetadata is not a function

问题描述

我在一个项目中使用 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

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

标签: typescriptinversifyjs

解决方案


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

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

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;

推荐阅读