0

这段代码昨天还在工作,但是当我今天醒来时,我从 typescript 类方法装饰器中得到了一个奇怪的行为。我正在为另一个装饰器定义一些简单的元数据并实现一个 DB Logger。我将把我的数据访问类的片段放在这里。但是我放置@dbTrackChg装饰器的每种方法都会出现此错误Cannot read property 'methodName' of undefined

TS版本:4.1.2

import mongoose, {
  Document,
} from 'mongoose';
import { 
  dbTrackChg,
  trackKeys,
} from '../decorators';

class MongoAccess<T extends Document> {
  /**
   * @description Create an instance of the MongoAccess class
   * @param Model {mongoose.model} Mongoose Model to use for the instance
   */
  constructor(public model: Model<T>) {}

  /**
   * @description Creates a new document on the Model
   * @param body {object} Body object to create the new document with
   * @returns {Promise} Returns the results of the query
   */
  @dbTrackChg({ type: trackKeys.create, multi: false })
  async create(body: Partial<T>): Promise<T> {
    const newDoc = new this.model(body);
    await newDoc.save();
    return newDoc;
  }
}

在这种情况下,我得到以下信息:

TypeError: Cannot read property 'create' of undefined
    at Object.<anonymous> (E:\Documents\CODE\WebDev\Lullo\backend\src\Data\MongoAccess.ts:62:33)
    at Module._compile (internal/modules/cjs/loader.js:1068:30)
    at Module.m._compile (E:\Documents\CODE\WebDev\Lullo\backend\src\node_modules\ts-node\src\index.ts:1056:23)
    at Module._extensions..js (internal/modules/cjs/loader.js:1097:10)
    at Object.require.extensions.<computed> [as .ts] (E:\Documents\CODE\WebDev\Lullo\backend\src\node_modules\ts-node\src\index.ts:1059:12)
    at Module.load (internal/modules/cjs/loader.js:933:32)
    at Function.Module._load (internal/modules/cjs/loader.js:774:14)
    at Module.require (internal/modules/cjs/loader.js:957:19)
    at require (internal/modules/cjs/helpers.js:88:18)
    at Object.<anonymous> (E:\Documents\CODE\WebDev\Lullo\backend\src\Services\ServicePlatform.ts:17:1)
    at Module._compile (internal/modules/cjs/loader.js:1068:30)
    at Module.m._compile (E:\Documents\CODE\WebDev\Lullo\backend\src\node_modules\ts-node\src\index.ts:1056:23)
    at Module._extensions..js (internal/modules/cjs/loader.js:1097:10)
    at Object.require.extensions.<computed> [as .ts] (E:\Documents\CODE\WebDev\Lullo\backend\src\node_modules\ts-node\src\index.ts:1059:12)
    at Module.load (internal/modules/cjs/loader.js:933:32)
    at Function.Module._load (internal/modules/cjs/loader.js:774:14)

这是定义类方法元数据的简单装饰器:

import 'reflect-metadata';

export enum trackKeys {
   create = 'create',
   update = 'update',
   delete = 'delete',
 }

export interface IDBTrack {
   type: trackKeys,
   multi: boolean,
 }

/**
  * Sets the metadata for the methods that need change logging of the MongoAccess class.
  * @param type type of operation. See {@link trackKeys}
  * @param multi indicates if affects multiple documents or a single document
  */
export function dbTrackChg(dbTrack: IDBTrack): Function {
  return function (target: any, key: string, desc: PropertyDescriptor): any {
    Reflect.defineMetadata(MetadataKeys.dbTrack, dbTrack, target, key);
  };
}

我不确定我是否弄乱了一些类型,但已经尝试了许多肮脏的解决方法,但没有任何效果。奇怪的是它昨天工作,所以我认为它与 TS 编译器有关。我有点在这上面扯头发。

这是我的tsconfig.json

{
  "compilerOptions": {

    /* Basic Options */
    "target": "es2019",      
    "module": "commonjs",    
    "lib": ["esnext", "dom"],
    "allowJs": false,        
    "sourceMap": true,       
    "outDir": "./build",     
    "rootDir": "./",
    "composite": true,
    "resolveJsonModule": true,

    /* Strict Type-Checking Options */
    "strict": false,
    "noImplicitAny": true,
    "strictNullChecks": true,
    "strictFunctionTypes": true,
    "strictBindCallApply": true,
    "strictPropertyInitialization": true,
    "noImplicitThis": true,
    "alwaysStrict": false,
    "noFallthroughCasesInSwitch": true,

    /* Module Resolution Options */
    "moduleResolution": "node",
    "baseUrl": "./",
    "paths": {
      "*": [
        "typings/*.d.ts",
        "*"
      ],
      "express": [
        "typings/express/*.d.ts"
      ],
      "express-serve-static-core": [
        "typings/express-serve-static-core/*.d.ts"
      ]
    },
    "types": ["node", "express"],
    "allowSyntheticDefaultImports": true,
    "esModuleInterop": true,
    "inlineSources": true,

    /* Experimental Options */
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,

    /* Advanced Options */
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true
  },
  "exclude": [
    "node_modules",
    "api/Controllers/swaggerDefinitions",
    "**/build",
    "**/docs"
  ]
}

更新

index.ts我正在从重新导出我的装饰器的文件中导入装饰器。我试图将导入更改为装饰器所在的实际文件,它突然起作用了;

改变了这个: DataAccess.ts

import { 
  dbTrackChg,
  trackKeys,
} from '../decorators';

对此:

import { 
  dbTrackChg,
  trackKeys,
} from '../decorators/dbLogger';

有人知道为什么会这样吗?我什至试图清空我的index.ts文件并只离开export * from './dbLogger',希望有一些出口冲突,但仍然无法让它工作。

它现在有效,但我不知道为什么。如果有人有想法,请赐教。

4

0 回答 0