Typescript - tsc compiler breaks my code - node.js

I wrote this code in Typescript
import redis from 'redis';
import Promise from 'bluebird';
const DEFAULT_REDIS_TTL = 7200; // 2 hours
export default class Redis {
readonly client : any;
ttl : number = DEFAULT_REDIS_TTL;
constructor(uri? : string, ttl : number = DEFAULT_REDIS_TTL) {
this.client = redis.createClient(uri);
}
...
}
export { Redis };
the compiler gives me this
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var redis_1 = require("redis");
var bluebird_1 = require("bluebird");
var DEFAULT_REDIS_TTL = 7200; // 2 hours
var Redis = (function () {
function Redis(uri, ttl) {
if (ttl === void 0) { ttl = DEFAULT_REDIS_TTL; }
this.ttl = DEFAULT_REDIS_TTL;
this.client = redis_1.default.createClient(uri);
this.client.on('error', function (error) {
console.error(error);
});
...
exports.Redis = Redis;
exports.default = Redis
I don't know why 'redis.createClient(uri);just becomeredis_1.default.createClient(uri);`
I get the following error when trying to run my code in node
build/Lib/Cache/Redis.js:11
this.client = redis_1.default.createClient(uri);
^
TypeError: Cannot read property 'createClient' of undefined
my tsconfig looks like this
{
"compilerOptions": {
"module": "mymodule",
"target": "es5",
"noImplicitAny": false,
"sourceMap": false,
"module": "commonjs",
"outDir": "build"
},
"include": [
"src/**/*.ts"
],
"exclude": [
"node_modules"
]
}
I run the compiler in main directory
tsc
I'm using node 6.7.2

Change your import to:
import * as redis from 'redis';
I don't think the typings for redis has a default export. Make sure you have the latest typings.
If you have the latest typings, import redis from 'redis'; should throw a compile time error.

Related

Sinon stub failed when upgrade ts-node to v10

Everything is ok when my ts-node version is 8.x ~ 9.x , but sinon stub failed when I upgraded ts-node to 10.x
The code likes below:
// file: ./lambda.ts
export const getAWSLambda = () => new AWS.Lambda({ region: AWS_DEFAULT_REGION });
export class AWSLambda {
private readonly lambda: AWS.Lambda;
constructor() {
this.lambda = getAWSLambda();
}
async invoke(params: ServerlessParams): Promise<ServerlessResponse> {
const response = await this.lambda.invoke({
// ...
}).promise();
return {};
}
}
// file: unit.test.ts
import sinon from 'sinon';
import * as lambda from './lambda';
describe('Lambda Unit Test', () => {
let lambdaService: lambda.AWSLambda;
let sandbox: sinon.SinonSandbox;
let getAWSLambdaStub: sinon.SinonStub;
let invokeStub: sinon.SinonStub;
before(() => {
sandbox = sinon.createSandbox();
});
beforeEach(() => {
invokeStub = sandbox.stub();
getAWSLambdaStub = sandbox.stub(lambda, 'getAWSLambda');
getAWSLambdaStub.returns({
invoke: () => ({
promise: invokeStub,
}),
});
lambdaService = new lambda.AWSLambda();
});
it('shound succeed to invoke', async () => {
invokeStub.resolves({
StatusCode: 200,
});
// -----------
// called real function, stub failed.
const res = await lambdaService.invoke();
expect(getAWSLambdaStub).to.be.calledOnce;
expect(invokeStub).to.be.calledOnce;
});
});
The stub failed, the real function was called.
sinon: 11.1.2
ts-node: 10.2.1
typescript: 3.9.7
node: 14.17.3
tsconfig.json:
{
"compilerOptions": {
"preserveConstEnums": true,
"module": "commonjs",
"esModuleInterop": true,
"target": "es6",
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"strict": true,
"moduleResolution": "node",
"sourceMap": false,
"outDir": "dist/src",
"allowJs": true,
"checkJs": true,
"noUnusedLocals": true,
"skipLibCheck": true
},
"ts-node": {
"transpileOnly": true,
"transpiler": "ts-node/transpilers/swc-experimental"
}
}
Everything is ok when my ts-node version is 8.x ~ 9.x , but sinon stub failed when ts-node is v10. Is there any change in the import of module for ts-node's swc ?
Add swc integration and new --transpiler option to use third-party transpilers for a massive speed boost on large codebases
I guess here is the cause of the problem, and I want to use ts-node v10, but I don't known how to fix the problems.

Importing Static Functions Typescript

I am trying to import a static class function into my main.js file but using the function after compiling with tsc I get:
TypeError: Cannot read property 'router' of undefined
at Object. (path/to/main.js:36:27)>
I have tried to assign it a type with no luck as well as using different methods of importing again with no luck...
I feel as if the answer is simple but cant seem to locate it in the TS docs and I'm just banging my head at this point.
Here is the class I am trying to export.
Session.ts
export class Session {
//Class Members
constructor() {
//Big constructor lots of this. =
};
//Creating the functions needed
logOut() {
delete Session.ssnsById[this.id];
delete Session.ssnsByCookie[this.authToken];
};
static router = function (req: Request, res: Response, next: Function) {
var cookie = req.cookies[Session.cookieName];
var session = cookie && Session.ssnsByCookie[cookie];
if (session) {
// If the session was last used more than |duration| mS ago..
if (session.lastUsed < new Date().getTime() - Session.duration)
session.logOut();
else {
req.session = session;
}
}
next();
};
}
module.exports = Session;
Importing into my main.ts
import { Session } from "./Session";
// Set up Session on req if available
app.use(Session.router); //<--
After running tsc we get built/main.js
const Session_1 = require("./Session");
// Set up Session on req if available
app.use(Session_1.Session.router); //<-This line throws the error.
Lastly here is my tsconfig.json used to compile
{
"compilerOptions": {
"module": "commonjs",
"esModuleInterop": true,
"target": "es6",
"noImplicitAny": true,
"noImplicitThis": true,
"moduleResolution": "node",
"sourceMap": false,
"baseUrl": ".",
"outDir": "built",
"paths": {
"*": [
"node_modules/*"
]
}
},
"include": [
"Src/**/*"
]
}
1: Please remove module.exports = Session;
2: Add a new file name 'custom.d.ts' in the root directory and add the following:
import { Session } from "./Session";
declare module 'express-serve-static-core' {
interface Request {
router?: typeof Session['router'],
}
}
3: Do this in the file where you imported Session class.
import {Request, Response, NextFunction} from 'express';
import { Session } from "./Session";
// Set up Session on req if available
app.use((req: Request, res: Response, next: NextFunction) => {
req.router = Session.router;
next();
});
You will have your router on the req :)
Removing module.exports = Session; Cleared the problem for me!

TypeError: Reflect.hasOwnMetadata is not a function

I am trying to use inversify with typescript and node.js. I am currently using node.js version 6.9.1, typescript version 2.6.2, and ECMAScript 6. When I try to run the node.js application, I keep receiving the following error, "TypeError: Reflect.hasOwnMetadata is not a function".
Following documentation I found online, by adding import "reflect-matadata" at the top of the inversify.config.js file, it seemed to work for awhile, but now the problem is back again.
In my inversify.config.ts file, I have the following code that gets called from my app.ts file:
export let initialize = async (): Promise<Container> => {
var container = new Container();
try {
if (!Reflect.hasOwnMetadata("inversify:paramtypes", ClassToAddInjectableTo)) {
decorate(injectable(), ClassToAddInjectableTo);
}
….
container.bind<interfaces.Controller>(TYPE.Controller).to(MyController1).whenTargetNamed('MyController1');
container.bind<interfaces.Controller>(TYPE.Controller).to(MyController2).whenTargetNamed('MyController2');
} catch (ex) {
throw ex;
}
}
This code exists in app.ts and it calls the code in the inversify.config.ts file:
setup = async () => {
try {
let container: Container = await initialize();
…..
} catch (err){
throw err;
}
}
The problem seems to be on the following line in node_modules/inversify/lib/annotation/decorator_utils.js:22:
if (Reflect.hasOwnMetadata(metadataKey, annotationTarget) === true) {
In the generated inversify.config.js file, the following code seems to be above the import "reflect-metadata":
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
require("reflect-metadata");
I noticed that the help I found online only indicated that I needed to add import "reflect-metadata".
Also, here is my tsconfig.json file:
{
"compilerOptions": {
"module": "commonjs",
"target": "ES6",
"moduleResolution": "node",
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"types": ["reflect-metadata"],
"lib": ["ES6"],
"sourceMap": true,
"inlineSources": true,
"pretty": true,
"outDir": "dist",
"rootDir": "src",
"noLib": false,
"declaration": true
},
"include": [
"src/**/*"
],
"exclude": [
"node_modules"
]
}
What could I be missing?
Update
For the issue above, I added the import "reflect-metadata" to the file inversify.config.ts file. However, I commented this import statement and added the import "reflect-metadata" to the app.ts file and now I am getting a different error:
throw new Error(ERRORS_MSGS.DUPLICATED_INJECTABLE_DECORATOR);
^
Error: Cannot apply #injectable decorator multiple times.
Now I found a post on the internet that seemed to describe indicate the adding import "reflect-metadata" adds a Reflect global variable. Also, I don't know if this helps but I removed the #injectable decorator from the controllers.
Try:
npm install reflect-metadata --save
Then import it only once in your entire application:
import "reflect-metadata"
If you are using inversify-express-utils make sure that your controllers are annotated with #controller not with #injectable. Also make sure that your coontrollers are imported once.
import "./controllers/some_controller";
import "./controllers/another_controller";
In case of failure during running jest test, add to the top of the spec file:
import "reflect-metadata";

typescript error running navalia example

I am trying to run this example from https://github.com/joelgriffith/navalia but for the light of me, I couldn't get it to work without error:
navaliatest.ts
/// <reference path="typings.d.ts" />
import { Chrome } from 'navalia';
const chrome = new Chrome();
async function buyItOnAmazon() {
const url = await chrome.goto('https://amazon.com');
const typed = await chrome.type('input', 'Kindle');
const clicked = await chrome.click('.nav-search-submit input');
chrome.done();
console.log(url, typed, clicked); // 'https://www.amazon.com/', true, true
}
buyItOnAmazon();
tsconfig.json
{
"files": [
"navaliatest.ts"
],
"compilerOptions": {
"noImplicitAny": false,
"target": "es6",
"moduleResolution": "node",
"paths": {
"*" : ["/usr/local/lib/node_modules/*"]
}
}
}
typings.d.ts
/// <reference path="/usr/local/lib/node_modules/navalia/build/Chrome.d.ts" />
declare module 'navalia' {
var Chrome: any;
export = Chrome;
}
Below are the versions:
MacBook-Pro:testcasperjs myusername$ node --version
v6.11.2MacBook-Pro:testcasperjs myusername$ npm --version
3.10.10
MacBook-Pro:testcasperjs myusername$ tsc --version
Version 2.4.2
This is the error I got although I do get .js file output:
MacBook-Pro:testcasperjs myusername$ tsc navaliatest.ts
../../../usr/local/lib/node_modules/navalia/node_modules/chrome-launcher/chrome-finder.ts(203,16): error TS2339: Property 'from' does not exist on type 'ArrayConstructor'.
../../../usr/local/lib/node_modules/navalia/node_modules/chrome-launcher/chrome-launcher.ts(99,15): error TS1056: Accessors are only available when targeting ECMAScript 5 and higher.
navaliatest.ts(3,10): error TS2305: Module ''navalia'' has no exported member 'Chrome'.
I am sure there is a stupid mistake somewhere but please could someone help me and take a look? Thanks.
You don't need to redeclare navalia. It has already been done for you at node_modules/navalia/build/index.d.ts given that moduleResolution is set to Node
You'll need to set module to commonjs so that you can run it in node
tsconfig.json
{
"files": [
"navaliatest.ts"
],
"compilerOptions": {
"noImplicitAny": false,
"target": "es6",
"module": "commonjs",
"moduleResolution": "Node"
}
}
navaliatest.ts (No change)
import { Chrome } from 'navalia';
const chrome = new Chrome();
async function buyItOnAmazon() {
const url = await chrome.goto('https://amazon.com');
const typed = await chrome.type('input', 'Kindle');
const clicked = await chrome.click('.nav-search-submit input');
chrome.done();
console.log(url, typed, clicked); // 'https://www.amazon.com/', true, true
}
buyItOnAmazon();
It'll create navaliatest.js with no errors, which can be run in node.

__awaiter is not defined

I'm using typescript v 1.8.9 in VSCode, nodejs 5.9.1 i have my file app.ts that has these lines
import {XController} from "./XController";
var xContrller=new XController();
xContrller.CallAsyncMethod(some args");
and XController is a class having async methode CallAsyncMethod
like this
public async CallAsyncMethod(url: string) {
await this.request.post(url);
}
this translates to __awaiter(void,...) in javascript but it crashes saying that __awaiter is not defined ??? any clues why this is happening and how to fix it.
Thanks
your tsconfig.json is most likely wrong. The following worked just fine:
tsconfig.json:
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"sourceMap": true
},
"exclude": [
"node_modules",
"typings/browser",
"typings/browser.d.ts"
],
"compileOnSave": true
}
ping.ts:
export async function ping() {
for (var i = 0; i < 10; i++) {
await delay(300);
console.log("ping");
}
}
function delay(ms: number) {
return new Promise(resolve => setTimeout(resolve, ms));
}
main.ts:
import {ping} from "./ping"
async function main() {
await ping();
}
main();

Resources