typescript - 如何导入自定义 EventEmitter 并避免 TS Error: 2339?
问题描述
我目前正在使用普通 JavaScript 制作的样板之上使用 TypeScript 配置项目。我的问题是在 preLaunchTask 中的 TS 编译期间出现的。我无法访问我在本地导入的自定义 EventEmitter 的“报告”属性。以下是来自 TS 的以下错误:
error TS2339: Property 'report' does not exist on type 'EventEmitter'.
下面是testing.ts文件:
'use strict';
import cors from 'cors';
import fs from 'fs';
import runner from '../../test-runner';
import express from 'express';
export default function (app: express.Application) {
app.route('/_api/server.js')
.get(function (req: express.Request, res: express.Response, next: Function) {
console.log('requested');
fs.readFile(__dirname + '/server.js', function (err, data) {
if (err) return next(err);
res.send(data.toString());
});
});
app.route('/_api/routes/api.js')
.get(function (req: express.Request, res: express.Response, next: Function) {
console.log('requested');
fs.readFile(__dirname + '/routes/api.js', function (err, data) {
if (err) return next(err);
res.type('txt').send(data.toString());
});
});
app.route('/_api/controllers/convertHandler.js')
.get(function (req: express.Request, res: express.Response, next: Function) {
console.log('requested');
fs.readFile(__dirname + '/controllers/convertHandler.js', function (err, data) {
if (err) return next(err);
res.type('txt').send(data.toString());
});
});
var error;
app.get('/_api/get-tests', cors(), function (req: express.Request, res: express.Response, next) {
console.log(error);
if (!error && process.env.NODE_ENV === 'test') return next();
res.json({ status: 'unavailable' });
},
function (req: express.Request, res: express.Response, next: Function) {
if (!runner.report) return next();
res.json(testFilter(runner.report, req.query.type, req.query.n));
},
function (req: express.Request, res: express.Response) {
runner.on('done', function (report) {
process.nextTick(() => res.json(testFilter(runner.report, req.query.type, req.query.n)));
});
});
app.get('/_api/app-info', function (req: express.Request, res: express.Response) {
var hs = Object.keys(res.header)
.filter(h => !h.match(/^access-control-\w+/));
var hObj = {};
hs.forEach(h => { hObj[h] = res.header[h] });
delete res.header['strict-transport-security'];
res.json({ headers: hObj });
});
};
function testFilter(tests, type, n) {
var out;
switch (type) {
case 'unit':
out = tests.filter(t => t.context.match('Unit Tests'));
break;
case 'functional':
out = tests.filter(t => t.context.match('Functional Tests') && !t.title.match('#example'));
break;
default:
out = tests;
}
if (n !== undefined) {
return out[n] || out;
}
return out;
}
这是我尝试导入的测试运行器:
var analyser = require('./assertion-analyser');
var EventEmitter = require('events').EventEmitter;
var Mocha = require('mocha'),
fs = require('fs'),
path = require('path');
var mocha = new Mocha();
var testDir = './tests'
// Add each .js file to the mocha instance
fs.readdirSync(testDir).filter((file) => {
// Only keep the .js files
return file.substr(-3) === '.js';
}).forEach((file) => {
mocha.addFile(
path.join(testDir, file)
);
});
var emitter = new EventEmitter();
emitter.run = () => {
let tests = [];
var context = "";
var separator = ' -> ';
// Run the tests.
try {
var runner = mocha.ui('tdd').run()
.on('test end', (test) => {
// remove comments
var body = test.body.replace(/\/\/.*\n|\/\*.*\*\//g, '');
// collapse spaces
body = body.replace(/\s+/g,' ');
var obj = {
title: test.title,
context: context.slice(0, -separator.length),
state: test.state,
body: body,
assertions: analyser(body)
};
tests.push(obj);
})
.on('end', () => {
emitter.report = tests;
emitter.emit('done', tests)
})
.on('suite', (s) => {
context += (s.title + separator);
})
.on('suite end', (s) => {
context = context.slice(0, -(s.title.length + separator.length))
})
} catch(e) {
throw(e);
}
};
module.exports = emitter;
还有我的tsconfig.json文件:
{
"compilerOptions": {
"target": "esnext",
"moduleResolution": "node",
"allowJs": true,
"noEmit": true,
"isolatedModules": true,
"esModuleInterop": true,
"noImplicitReturns": true,
"lib": [
"dom",
"es6"
],
"outDir": "public",
"sourceMap": true
},
"include": [
"src",
]
}
我试图尽我所能缩小我的问题范围,但我不知道为什么进口和出口似乎没有回应一个和另一个。最近我一直在解决很多重新配置错误,所以我的大脑可能会想太多。如果还有其他可用的代码,请随时告诉我。
解决方案
我调整了我的“preLaunchTask”以完全匹配我的 TS 编译器脚本名称——这不是问题。我得到的 TypeScript 错误,即我的测试运行程序上的“报告”属性无效,是由于测试运行程序文件中的旧语法导致的,这是由于原始测试运行程序作者将属性直接分配给 EventEmitter 的实例。为了让 TS 编译器满意,我将测试运行程序代码调整为基于类的设置,将“报告”添加到构造函数中,从而避免来自原始测试运行程序的“void”或“() => void”返回值。
test-runner2.js:
import analyser from '../../assertion-analyser';
import { EventEmitter } from 'events';
import Mocha from 'mocha';
import fs from 'fs';
import path from 'path';
import { connect } from 'http2';
const mocha = new Mocha();
const testDir = './tests';
// Add each .js file to the mocha instance.
fs.readdirSync(testDir).filter(file => {
return file.substr(-3) === '.js';
}).forEach(file => {
mocha.addFile(
path.join(testDir, file)
);
});
class TestEmitter extends EventEmitter {
constructor() {
this.report = []
}
run = () => {
// Run the tests...
let tests = [];
let context = '';
let separator = ' ~> ';
try {
const runner = mocha.ui('tdd').run()
.on('test end', test => {
// remove comments
let body = test.body.replace(/\/\/.*\n|\/\*.*\\/g, '');
// collapse spaces
body = body.replace(/\s+/g, '');
const obj = {
title: test.title,
context: context.slice(0, -separator.length),
state: test.state,
body: body,
assertions: analyser(body)
};
tests.push(obj);
})
.on('end', () => {
emitter.report = tests;
emitter.emit('done', tests)
})
.on('suite', (s) => {
context += (s.title + separator);
})
.on('suite end', (s) => {
context = context.slice(0, -(s.title.length + separator.length))
});
} catch(err) {
throw(err);
}
}
}
export default TestEmitter;
tsconfig.json:
{
"compilerOptions": {
"target": "es5",
"moduleResolution": "node",
"allowJs": true,
"noEmit": true,
"isolatedModules": true,
"esModuleInterop": true,
"noImplicitReturns": true,
"lib": [
"dom",
"es6"
],
"outDir": "public",
"sourceMap": true
},
"include": [
"src",
]
}
希望这可以帮助其他尝试将 TS 添加到香草 JS 样板的人。我也发布了我的配置文件。使用Node默认类class
。extends
EventEmitter
推荐阅读
- flutter - 当列表视图的项目在颤动的视口中可见时,如何更改项目颜色并执行一些操作?
- typescript - Firebase 中的异步函数甚至在函数体完成执行之前就解决了 Promise
- python - 调节熊猫数据框
- python - 类型错误:dtype '
' 不明白 ; 在转换 DataFrame 的日期时? - c++ - 并行循环中的 CPU 使用率低
- javascript - Bootstrap 4.5 动画显示初始状态时打开页面时折叠
- reactjs - 我无法在 React 中对我的项目执行“npm install”。当我运行“npm install”时,我得到错误消息
- reactjs - 在 React 中更改路由更改的状态
- vue.js - 页面重新加载 Nuxt.js 时出现未定义数据错误
- pine-script - 在最后一个柱上查找系列值(Pine Script,Tradingview)