My class created doesn't export an object - javascript

I need to create the class ShoppingCart in the file ShoppingCart.js and export it to a test file and i get the error that my class is not a constructor
I know the problem is not in import export because before creating the js file i got the error that it couldn't find the module. I also tried creating a new instance of the class inside the file and it worked
file ShoppingCart.js
class ShoppingCart{
constructor(name){
this.name=name
}
}
module.exports = { ShoppingCart}
The code for my test file is
const ShoppingCart = require("./ShoppingCart")
new ShoppingCart()
when i run the test file i get
TypeError: ShoppingCart is not a constructor

You are currently exporting an object with a property of ShoppingCart:
module.exports = { ShoppingCart }
// ^^ object ^^
Just export ShoppingCart:
module.exports = ShoppingCart;
Or, when importing, reference the ShoppingCart property of the object:
const { ShoppingCart } = require("./ShoppingCart")

You're exporting an object with a ShoppingCart property.
Either:
Change your export to module.exports = ShoppingCart;, or
Change your require to const { ShoppingCart } = require("./ShoppingCart");
If you're using a modern version of Node.js, you might consider using ESM (ECMAScript Modules) instead (export/import):
export class ShoppingCart{
constructor(name){
this.name=name
}
}
and
import { ShoppingCart } from "./ShoppingCart.js";
new ShoppingCart();
That uses JavaScript's native modules rather than Node.js's CommonJS variant. Over the new couple of years, this will become the standard way of doing it. For now, to use ESM you use the --experimental-modules flag and a package.json containing type: "module". (Or, instead of the package.json type field, you can use the file extension .mjs.) Details here.

Related

Global object in node.js

I have in my website a class named classPerson which is in dir /foo. I need to use it in dir ./bar, but since /bar is not allowed to import from /foo i do the following:
/foo:
const classPerson = new classPerson();
Object.assign(window, { classPerson });
/bar:
const person = window.classPerson.
I need to achieve a similar thing in node.js. How can i do it (having no window)
Depending on your project setup, you can use either the built-in require() method or the es6 import module syntax.
in /foo.js
export class ClassPerson { ... } // add the export keyword to the class definition
export const classPersonInstance = new classPerson(); // add the export keyword to the class instance if you want to use the same instance
in /bar.js
const foo = require('./foo.js');
const instance = foo.classPersonInstance;
// or
import { classPersonInstance } from './foo.js';
NOTE
To be able to use the import syntax, you should do some additional configuration
Here is the nodejs documentation for ECMAScript Modules

How to export property of a interface/Object like Javascript in TypeScript

As we known, the commonJS module's exports is a JS Object commonly. We can access the specific method easily like const { methodA } = require('module').
How can we impl the .d.ts(types declaration file), allowing the typescript user to enjoy the similar import experience?
We hope to do like that:
// JavaScript
const sdk = require('module')
sdk.methodA(params)
// Or
const { methodA } = require('module')
methodA(params)
// Typescript also can be:
import sdk from 'module'
sdk.methodA(params)
// Or
import { methodA } from 'module'
methodA(params)
That is my current impl:
export * from './interface' // a .d.ts file that includes all interface, is it necessnary exported to users?
interface Instance {
methodA: (params: anthorInterface) => Promise<ResponseInterface>
}
declare const sdk: Instance
export default sdk
But the syntax import { methodA } from 'method' doesn't work, though, the default behavior works fine.
Could you give me any suggestions? Thank you a lot.

How can I describe a JavaScript class static factory method in TypeScript typings with default export?

I'm developing a vanilla JavaScript library and have a JS class defined like this:
class MyClass {
static create() {
return new MyClass();
}
doOneThing() {
// ...
return this;
}
doOtherThing() {
// ...
return this;
}
}
module.exports = MyClass;
So I can use dsl-like syntax:
MyClass
.create()
.doOneThing()
.doOtherThing();
And I'm trying to add d.ts typings file for this class for fellow TypeScript developers could use it too.
Best I've been able to get so far:
export interface MyClassInstance {
doOneThing(): MyClassInstance;
doOtherThing(): MyClassInstance;
}
export interface MyClassStatic {
create(): MyClassInstance;
}
declare const MyClass: MyClassStatic;
export default MyClass;
So it works for TypeScript:
import MyClass from "./src/MyClass";
But in a JavaScript file my IDE offers me this via autocomplete tool:
MyClass.default.create();
I've figured I could add mandatory destructuring, exporting my class wrapped in an object:
module.exports = {MyClass};
Then both TS and JS work the same way. But I rather won't.
So I wonder, if there is another way to do that - to have both static method and default export worlkng both in JS and TS
UPDATE 1
It appears I can declare a class instead of an interface in my .d.ts file like this:
declare class MyClass {
static create(): MyClass;
doOneThing(): this;
doOtherThing(): this;
}
export default MyClass;
Both JS and TS seems to work fine with it, but I'm still checking out if it's OK or kinda "don't" or bad practice.
UPDATE 2
Well, it seems it's the best I can get.
I also checked DefinitelyTyped repo and some modules use class declaration in their typings, so I guess it's OK.
Check the section export = and import = require():
// change to
export = MyClass;
If is not for the exercise in itself, you could write in TS and pass --declaration to the compiler and let it generate the .d.ts file

Importing external dependencies in Typescript

I am a newbie in typescript/node. I have a typescript file "order.ts" from which I would like to import an external config dependency from "config.ts"
My config file code is as below
let config = {
mongoAddress: "mongodb://localhost:27017/dts",
dataDirectory: "../../data/"
};
module.exports = config;
I am importing the config file in the order file as below
import { config } from "../../config";
However I am getting the TS compiler throwing error "... file not a module". Any clues how I should I be importing my external dependency in typescript
The main part here is you want to export your object instance. You're on the right track with that, but there may be an easier way for you.
In this case something like wrapping it in a class and exporting that:
export class Config {
mongoAddress = 'mongodb://localhost:27017/dts';
dataDirectory = '../../data/';
}
Notice the export before class. The same can be applied to interfaces, enums etc. By exporting it this way you can then import it and initialise it:
import { Config } from '../config';
var c = new Config();
console.log(c.mongoAddress);
This will not make it a variable, like in your original example, but you'll simply wrap it in a class. This is also why you have to initialise it first using new Config().
Now, I'm assuming you want these properties simply to be accessed globally. And perhaps even static/readonly, so you don't have to initialise the class each time. Making use of the static typing of TypeScript, the sample would in this case be better refactored to something like this:
export class Config {
public static readonly mongoAddress: string = 'mongodb://localhost:27017/dts';
public static readonly dataDirectory: string = '../../data/';
}
With this, calling it is even less obtrusive - and very type safe:
console.log(Config.mongoAddress);
console.log(Config.dataDirectory);
Now exporting this way is just one of the options. It actually depends entirely on the library structure you're using throughout your application (or from third partie libraries, for that matter). It's a bit of dry reading, but I recommend you have a look at the different structures to get acquainted with terms like UMD and modules and how they relate to an import.
Hope this helps!
There are 2 ways you can do import and export.
1) default export
// config.ts
export const config = {
mongoAddress: "mongodb://localhost:27017/dts",
dataDirectory: "../../data/"
};
export default config;
// your other file
import configs from './config';
Note: Here you can give any name for the imported module;
2) normal export with exact declaration name while importing.
// config.ts
export const config = {
mongoAddress: "mongodb://localhost:27017/dts",
dataDirectory: "../../data/"
};
// your other file
import { config } from './config';
Note: Here you have to give the exact name of the module that you exported.
Best practices to follow while exporting configs.
create a static class with static variables in the code. Which likely means that these configs are fixed stuffs.
module.exports is the node syntax for exporting modules. Typescript has a keyword names export so you can just use this:
export const config = {
mongoAddress: "mongodb://localhost:27017/dts",
dataDirectory: "../../data/"
};

Is it possible to use nodejs style modules in typescript?

In node, I can define a module like this by setting the properties of exports object :
module.js
exports.fun = function (val) {
console.log(val);
};
and the ask for it using var module = require('module') in and the use the module.fun() function.
Is it possible to define the module in TypeScript like this:
module.ts
exports.fun = function (val :string) {
console.log(val);
};
and then import the module in some other file using node like syntax, say, import module = require('module.ts') so that it compiles to nodejs but, if now I use module.fun() in some .ts file, it should give me an error if the arguments don't match the type specified in module.ts file.
How can I do this in Typescript?
Yes it is possible to use the true js syntax. You are receiving the error since you are using the import keyword which expects the imported file to use the export keyword. If you want the js exports.foo syntax you should use var instead of import. The following will compile/work just fine:
var module = require('module.ts')
What you've described basically exactly how external modules in TypeScript work.
For example:
Animals.ts
export class Animal {
constructor(public name: string) { }
}
export function somethingElse() { /* etc */ }
Zoo.ts
import a = require('./Animals');
var lion = new a.Animal('Lion'); // Typechecked
console.log(lion.name);
Compile with --module commonjs and run zoo.js in node.

Categories

Resources