这段代码昨天还在工作,但是当我今天醒来时,我从 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'
,希望有一些出口冲突,但仍然无法让它工作。
它现在有效,但我不知道为什么。如果有人有想法,请赐教。