How to use #implements - node.js

I have a Model class (in nodejs) and I want to implement it from AuthorizationCodeModel.
I want WebStorm detect that my model implemented the interface and suggest me auto complete
Interface.
Model:
/**
* #implements AuthorizationCodeModel
*/
class Model {
}
the #implements AuthorizationCodeModel is not working. How can I use JSDoc?

example interface in typescript
interface ClockInterface {
currentTime: Date;
}
class Clock implements ClockInterface {
currentTime: Date;
constructor(h: number, m: number) { }
}
https://www.typescriptlang.org/docs/handbook/interfaces.html
What's the difference between 'extends' and 'implements' in TypeScript
JSDOC examples: http://usejsdoc.org/tags-implements.html
If autocomplete in Webstorm not worked, try to set reference path in js file
/// <reference path="components/someClass.js"/>
/// <reference path="components/someInterface.js"/>
/// <reference path="components/AuthorizationCodeModel.js"/>
/**
* #implements AuthorizationCodeModel
*/
class Model { }
Reference paths also use for autocomplete in some popular IDEs
https://madskristensen.net/blog/the-story-behind-_referencesjs
https://www.jetbrains.com/help/webstorm/configuring-javascript-libraries.html
https://intellij-support.jetbrains.com/hc/en-us/community/posts/206352279-How-to-not-reference-other-js-files
intellisense and code complete for DefinitelyTyped (TypeScript type definitions) on WebStorm IDE

Related

Cannot find name inside namespace

I'm trying to separate interfaces and implementations inside typescript, so I choose to use module feature. However, I always receive Cannot find name even when I use <reference path=.../>. Here is my code:
IUserService.ts
namespace Service {
export interface IUserService {
login(username: string, password: string): void;
}
}
UserService.ts
/// <reference path="./IUserService.ts" />
namespace Service {
export class UserService implements IUserService {
constructor() {}
}
Then tsc always complains that Cannot find name IUserService inside UserService.ts. I follow what the documentation said about namespace but it's not working for me. What should be the fix for this?
Two advices from the TypeScript handbook:
Do not use the /// <reference ... /> syntax;
Do not use namespaces and modules together. Node.js already provides modules, so you don't need namespaces.
Here is a solution:
// IUserService.d.ts
export interface IUserService {
login(username: string, password: string): void;
}
// UserService.ts
import { IUserService } from "./IUserService";
export class UserService implements IUserService {
constructor() {
}
login(username: string, password: string) {
}
}
You'll have to define a tsconfig.json file. The /// <reference ... /> statement is replaced by a configuration file (tsconfig.json) since TypeScript 1.5 (section "Lightweight, portable projects").
Related : How to use namespaces with import in TypeScript and Modules vs. Namespaces: What is the correct way to organize a large typescript project? .

Access class inside function

I have a ready() function which contain an es6 class.
I would like to instantiate this class outside the function, however I didn't succeed in making this working.
I don't want to use return function because the function can have more than one class.
Here is an example of what i want to do :
function ready(api) {
class A extends api.C {
contructor() {
this.foo = "bar";
}
}
class B extends A {
contructor() {
this.bar = "foo";
}
}
}
let classA = ready.A; // Here is the problem : I would like to access to the class prototype
The reason is my application have some plugins using remi npm package, and I want to export classes shared between all plugins.
I don't know if it's possible, anybody have an idea ?
[EDIT] :
First thanks all for your hep, In fact I need to be more accurate in my issue.
That's true, I can return back both classes through a classic return. But let me explain what I want to do exactly :
I have a core application which have some plugins. Plugins can be internally integrated to core, or through a classic NPM install. As explained above I use remi plugin loader.
The desired rules are the following : Each plugin get a core API access through a callback. Each plugin can expose classes to be used in other plugins. Each plugins can have inheritance for those exposed (ie exported) plugins.
Here is how I describe a plugin :
/**
* This class is a sample plugin
* #class
*/
class Sample {
constructor(api) {
this.api = api;
}
/**
* Shows a test log
*/
test() {
console.log("======> I'm working !");
}
}
function loaded(api) {
let s = new Sample(api);
}
module.exports = (api, options) => {
};
module.exports.attributes = {
loadedCallback: loaded,
name: "sample-plugin",
version: "0.0.0",
category: "misc",
description: "I'm a sample plugin",
classes: [Sample]
};
The core plugin manager will load the first time all plugins, and will register into an array all classes protoypes exported into the classes attributes property.
Then the loaded(api) function is called and classes can be instantiated through api.classes object.
In another plugin, I can do this :
function loaded(api) {
let sample = new api.classes.Sample(api);
}
And I can instantiate a class described in another plugin.
That's the idea.
However I would like to do a more complex API usage with the multiple inheritance, for example :
Plugin A exposes class A
Plugin B exposes class B extends A
Plugin C exposes class C extends B
To be more clear, I would like to export globally some classes, to get a shared access between NPM modules
You can return class A from ready function, so after calling ready you can access A class
function ready(api) {
class A extends api.C {
contructor() {
this.foo = "bar";
}
}
class B extends A {
contructor() {
this.bar = "foo";
}
}
return {A : A};
}
let classA = ready(api).A;

Typescript exporting namespace defined in multiple files

I am currently working on my first Typescript project. After going through the official documentation and watching some courses (egghead), I thought it was time to write real code - not just samples.
I am using:
typescript#rc (~2.0.2)
Visual Studio Code (~1.4.0)
Windows 10
So I am working on a node module. My question here is about code structuring.
Here is how my project looks like:
src/
|____ core/
| |____ core.ts
| |____ components.ts
| |____ systems.ts
|____ input/
| |____ input.system.ts
| |____ keyboard.ts
|____ app.ts
Below is a sample of each files:
core.ts
/// <reference path="../core/components.ts" />
namespace Core {
export interface IEntity {
x: number
y: number
components: [Components.IComponent]
update(dt: number): void
}
export class Entity implements IEntity {
x: number
y: number
components: [Components.IComponent]
update(dt: number): void{
// do something with the coordinates
}
}
}
components.ts
namespace Components{
export interface IComponent {
update(dt: number): void
// some other stuff here...
}
}
systems.ts
namespace Systems{
export interface ISystem{
update(dt: number): void
// some other stuff here...
}
}
input.system.ts
/// <reference path="../core/systems.ts" />
namespace Systems{
export class InputSystem implements ISystem{
update(dt: number): void{
// do something here
}
// some other stuff here...
}
}
keyboard.ts
/// <reference path="../core/components.ts" />
namespace Components{
export class Keyboard implements IComponent{
update(dt: number): void{
// do something here - Catch key up / down
}
// some other stuff here...
}
}
app.ts
/// <reference path="./core/core.ts" />
/// <reference path="./core/components.ts" />
/// <reference path="./core/systems.ts" />
/// <reference path="./input/input.system.ts" />
/// <reference path="./input/keyboard.ts" />
export = {Core, Components, Systems}
What I want to do here is having 3 main namespaces Core, Components and Systems. Then if in another project this module is imported, we could do something like:
other.module.ts
// load module from node
import * as mymodule from "mymodule"
module A {
class A extends mymodule.Core.Entity{
constructor() {
this.components.push(new mymodule.Components.Keyboard());
}
}
export function main(): void{
var systems: [mymodule.Systems.ISystem];
systems.push(new mymodule.Systems.InputSystem());
// other systems could be pushed Here
for(var system in systems){
system.update(0.5);
}
}
}
The error that I am getting is in app.ts where for all namespaces compiler says:
cannot re export name that is not define
Is there something wrong with what I am doing?
I was also wondering if I should export using default in app.ts? like:
export default {Core, Components, Systems}
Would that help when importing my module?
Thanks,
Ed.
Not sure if my question was clear enough. I found a solution though, and would like your opinion.
So, I removed all the namespaces from my files. Which means that now all my files are modules.
Then at the root of my solution I create three files:
_core.ts
export * from "./core/core"
_components.ts
export * from "./core/components"
export * from "./input/keyboard"
_systems.ts
export * from "./core/systems"
export * from "./input/input.controller"
Now in my app.ts I can simply import those new files, like this.
import * as Core from "./_core"
import * as Components from "./_components.ts"
import * as Systems from "._/systems.ts"
export = {Core, Components, Systems}
What do you think? Any potential issue by doing so?
Thanks,
Ed.

Trying to get namespace behavior in TypeScript to work in RequireJS

I'm trying to use TypeScript to create a common library for a set of related web sites. I started off code like this:
module Lib {
export module Tools {
export class Opener {
public Path: string;
public static Open(): boolean { /* ... */ }
}
export class Closer { /* ... */ }
}
export module Controls {
export class InfoDisplay { /* ... */ }
export class Logon { /* ... */ }
}
export module Entities {
export class BigThing { /* ... */ }
export class LittleThing { /* ... */ }
}
}
var Initial: boolean = Lib.Tools.Opener.Open();
var CustomOpener: Lib.Tools.Opener = new Lib.Tools.Opener();
This worked quite well and allowed me to use some of TypeScript's nice features, like static methods and namespaced class names. As the project has grown, however, the need to use a module system for dependency resolution has become clear. My problem is that I'm a RequireJS noob so I can't quite figure out how get preserve the desirable features mentioned above to work in my project once RequireJS is in the mix. Here's my best attempt so far (which, to save space, only shows the code trail for Opener):
// ---- Opener.ts --------------------------------------------------------
/// <reference path="../typings/requirejs/require.d.ts"/>
class Opener {
public Path: string;
public static Open(): boolean { /* ... */ }
}
export = Opener;
// ---- Tools.ts --------------------------------------------------------
/// <reference path="../typings/requirejs/require.d.ts"/>
import Opener = require("./Opener");
import Closer = require("./Closer");
class Tools {
public Opener: Opener = new Opener();
public Closer: Closer = new Closer();
}
export = Tools;
// ---- ReqLib.ts --------------------------------------------------------
/// <reference path="../typings/requirejs/require.d.ts"/>
import Tools = require("./Tools");
class ReqLib {
public Tools: Tools = new Tools();
}
export = ReqLib;
// ---- App.ts --------------------------------------------------------
import ReqLib = require("./ReqLib");
var RL: ReqLib = new ReqLib();
var Initial: boolean = RL.Tools.Opener.Open(); // <== red squiggles
var CustomerOpener: ReqLib.Tools.Opener = new ReqLib.Tools.Opener(); // <== red squiggles
Visual Studio doesn't like the last two lines. It can't see the static method in the first line and it just flat out doesn't like the second because it looks like instances are being used as types. It's also the more troubling case because TypeScript kind of needs to have types to work with.
In your code RL.Tools.Opener is resolving to new Opener(); The static public static Open() does not exist on an instance but instead exists on the class Opener, hence the compiler error.
Suggestion : don't make it static. There might be other suggestions but now you know the reason for the error.
UPDATE
for new ReqLib.Tools.Opener(); you need to do new ReqLib().Tools.Opener;

Typescript references misunderstanding

I have a TypeScript d.ts file which I'm referencing from another file, but for some reason the exported class definitions don't seem to be recognised.
foo.d.ts
export declare class MyClass {
constructor();
public MyFunc(id: number): void;
}
bar.ts
/// <reference path="typings/MyClass.d.ts" />
class BarClass {
private something: MyClass;
constructor(thing: MyClass) {
this.something = thing;
}
}
That's about as simple an example I can give, but when doing this I get Could not find symbol 'MyClass'
I'm sure this used to work prior to updating TypeScript to the latest version, but on checking the breaking changes, I can't see anything which would cause the issue.
Does anyone have any ideas here?
Remove the export keyword. i.e
export declare class MyClass {
constructor();
public MyFunc(id: number): void;
}
to
declare class MyClass {
constructor();
public MyFunc(id: number): void;
}
Reason: The export keyword at the root of the file is reserved for external modules. A video on external modules : http://www.youtube.com/watch?v=KDrWLMUY0R0&hd=1

Resources