TypeScript Resolve right Namspace failed - javascript

I've the problem that I'am using some external libs which has nearly equal namespaces like:
declare module Test.Internal.Blubb {
interface IAnzeige {
Option: Internal.AnzeigeOptionen.IAnzeigeOptionen;
}
}
declare module Internal.AnzeigeOptionen {
interface IAnzeigeOptionen {
AnzeigeX: number;
AnzeigeY: number;
}
}
and this code will not compile because it's showing the error:
Test.Internal has no exported member AnzeigeOptionen
the row:
Option: Internal.AnzeigeOptionen.IAnzeigeOptionen;
shows this error.
Is there a way to bypass this Problem?
I'm using TypeScript 1.4 and VS 2013 Update 4

The problem with the code is that when the compiler sees line Internal.AnzeigeOptionen, it tries to resolve Internal as Test.Internal due to namespace collision.
You can re-import the Internal module with another name outside your Test.Internal declaration.
import m = Internal;
declare module Test.Internal.Blubb {
interface IAnzeige {
Option: m.AnzeigeOptionen.IAnzeigeOptionen;
}
}
declare module Internal.AnzeigeOptionen {
interface IAnzeigeOptionen {
AnzeigeX: number;
AnzeigeY: number;
}
}

Related

Custom cypress commands is not assignable to parameter of type 'keyof Chainable<any>

In a .ts file I create a test to try and access a custom created command from command.js, createInbox function is underlined with red with the following message : Property 'createInbox' does not exist on type 'cy & EventEmitter
it.only('dsdsds', () => {
cy.createInbox().then((inbox) => {
console.log(inbox);
// { id: '...', emailAddress: '...' }
});
})
My command.js file look like this
const { MailSlurp } = require("mailslurp-client");
const mailslurp = new MailSlurp(Cypress.env("mailSlurpApiKey"));
Cypress.Commands.add("createInbox", () => {
return mailslurp.createInbox();
});
Cypress.Commands.add("waitForLatestEmail", (inboxId) => {
return mailslurp.waitForLatestEmail(inboxId);
});
I understand that I have to rename command.js to ts, however when I do that all custom commands is underlined with red with the following error :
Argument of type '"waitForLatestEmail"' is not assignable to parameter of type 'keyof Chainable
How could I fix this?
Solved by adding custom chainable interface to support folder
declare namespace Cypress {
interface Chainable {
createInbox(): Chainable<any>;
waitForLatestEmail(inboxId: number): Chainable<any>;
}
}
I had this problem aswell!
My solution:
I had my *.d.ts files located inside the cypress/support folder, right next to the *.ts files with all the custom commands. Moving those outside(!) the "support"-folder and into another one called "definitionFiles" (for example) worked beautifully!

How to import a variable from a JavaScript file and use it in TypeScript?

I'm trying to make a userscript in TypeScript using Webpack and Hogan.js pre-compiled templates.
For it to work, I need to import a compiled file, carousel_inner.js. This file is auto-generated, so no modifications to it are allowed.
if (!!!templates) var templates = {};
templates["carousel_inner"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("<a class=\"carousel-");t.b(t.v(t.f("class",c,p,0)));t.b("\" href=\"\" style=\"background-image: url(");t.b(t.v(t.f("background-image",c,p,0)));t.b(")\">\r");t.b("\n" + i);t.b(" <div>\r");t.b("\n" + i);t.b(" <h4>");t.b(t.v(t.f("h4",c,p,0)));t.b("</h4>\r");t.b("\n" + i);t.b(" <h5>");t.b(t.v(t.f("h5",c,p,0)));t.b("</h5>\r");t.b("\n" + i);t.b(" <p>");t.b(t.v(t.f("p",c,p,0)));t.b("</p>\r");t.b("\n" + i);t.b(" </div>\r");t.b("\n" + i);t.b("</a>");return t.fl(); },partials: {}, subs: { }});
I'm trying different strategies to import the templates variable and export it for usage elsewhere, but I always end up with a "templates is not defined" error.
Here's a failed attempt.
// index.ts
import "./js/carousel_inner";
export default templates;
// main.ts
import templates from "./templates";
console.log(`templates: ${templates}`);
The project is here.
Make a declaration type file.
carousel_inner.d.ts (.d.ts IS REQUIRED)
declare module "carousel_inner.js" {
interface types {
[index:string]:unknown;
}
/* OR */
type types = unknown;
/* OR */
const types:unknown;
export default types;
}
It will give types to a file that is being imported.
I use the following for importing sql files occasionally.
declare module "*.sql" {
const content: string;
export default content;
}
Just use the type you want instead of unknown.

Typescript ReconnectingWebSocket fails to call constructor

When I attempt to create a new ReconnectingWebSocket I get the following:
reconnecting_websocket_1.default is not a constructor
The typescript code is:
import ReconnectingWebSocket, { Options } from 'reconnecting-websocket';
export class RealtimeClient {
private reconnectingWebSocket: ReconnectingWebSocket
constructor(private url: string, private dispatch: IDispatcher) {}
public connect() {
const wsOptions: Options = {
minReconnectionDelay: 1000,
reconnectionDelayGrowFactor: 1.0,
connectionTimeout: 2000,
}
this.reconnectingWebSocket = new ReconnectingWebSocket(this.url, [], wsOptions)
this.reconnectingWebSocket.onmessage = this.onMessage
}
/* ... */
}
At runtime, the resulting javascript in chrome dev tools shows that reconnecting_websocket_1 is the ReconnectingWebSocket class as expected, however default is undefined, which I believe is the root cause of the failure.
this.reconnectingWebSocket = new reconnecting_websocket_1.default(this.url, [], wsOptions);
this.reconnectingWebSocket.onmessage = this.onMessage;
NB:
I am compiling to ES5 javascript (via tsconfig.json target).
I have a non-dev dependency on reconnecting-websocket
"reconnecting-websocket": "^4.0.0-rc5"
Add compiler option esModuleInterop to your tsconfig.json.
You might also want to look at socket.io-client, which is slightly bigger, but not abandoned 3 years ago.

Static readonly member assignation => TypeError: XXX is not a constructor

I'm facing an issue with Typescript/Jest with static readonly member. Here a basic example.
The project structure is based on this starter project : https://github.com/alexjoverm/typescript-library-starter if it can help to reproduce issue.
point.ts
import {PointUtil} from "./pointUtil";
export class Point
{
public x: number;
public y: number;
public constructor(x: number, y: number)
{
this.x = x;
this.y = y;
}
public dummyCalc() : number
{
return this.x + this.y + PointUtil.origin.x + PointUtil.origin.y;
}
}
pointutil.ts
import {Point} from "./point";
export class PointUtil {
public static readonly origin: Point = new Point(12, 2);
}
repl.test.ts
import {Point} from "../src/point";
describe("REPL test", () => {
it("dummy test", () => {
expect(new Point(1, 1).dummyCalc()).toEqual(16)
});
});
Error
When run the test suite I'm getting
● Test suite failed to run
TypeError: _point.Point is not a constructor
3 | export class PointUtil {
4 | public static readonly origin: Point = new Point(12, 2);
> 5 | }
6 |
at src/pointUtil.ts:5:24
at Object.<anonymous> (src/pointUtil.ts:7:2)
at Object.<anonymous> (src/point.ts:1:4237)
at Object.<anonymous> (test/repl.test.ts:1:1181)
What does this error mean?
Typescript version is 2.7.2
jest 22.0.2
ts-jest 22.0.0
The error is easier to understand if you add a console log to pointutil.ts:
import {Point} from "./point";
console.log('Point:', Point);
export class PointUtil {
public static readonly origin: Point = new Point(12, 2);
}
This shows that Point is undefined (which is not a constructor :-) The reason this happens is that point.ts and pointUtil.ts import each other and create a circular module dependency. It is not related to the test, as the error would be triggered by any module that imports point.ts.
When module point.ts is evaluated, and it triggers the evaluation of pointUtil.ts, the value of the imported Point in pointUtil.ts will be undefined until the evaluation of the point.ts module has finished. However, since the definition of the static origin property amounts to doing
PointUtil.origin = new Point(12, 2);
it means that Point gets used before pointUtil.ts (and hence point.ts) have been evaluated, leading to the error.
Module point.ts also uses an import from pointUtil.ts, but this is inside the dummyCalc method, so it isn't evaluated during the initial module evaluation. This means that if you import pointUtil.ts before point.ts in repl.test.ts, the evaluation order of point.ts and pointUtil.ts is reversed, and the error will go away, since point.ts won't fail on an initially undefined PointUtil.
import './pointUtil'
import {Point} from './point'
describe("REPL test", () => {
..
});
This is a hacky solution though, so it is better to avoid the cycle and put definitions that immediately require Point in the point.ts module itself. As a matter of fact, origin is more suitable as a static property on Point anyway.

Javascript Unable to validate computed reference to imported namespace

Not sure if I need to add another jshint library or if I should do this a different way.
I have a file (for explanations reasons we'll call it stuff-functions.js) that exports functions like this...
export function a() {
return 'stuff';
}
export function b() {
return 'more stuff';
}
export function c() {
return 'even more stuff';
}
In another file I'm importing that file and calling that function by an argument...
import * as stuffFunctions from './stuff-functions'
export default class someReactClass {
myFunc(functionToCall) {
return stuffFunctions[functionToCall]();
}
...
}
It works fine, but in the console I'm getting an eslint error...
Unable to validate computed reference to imported namespace 'stuffFunctions'
So, should I go about this differently or hunt down some sort of eslint library that allows for this?
EDIT...
I've added this line to stop the error // eslint-disable-line
I was just curious if there was a better way to do this. Maybe something like...
import {a, b, c} from './stuff-functions';
export default class someReactClass {
myFunc(functionToCall) {
const myStuffFunctions = {
a: a,
b: b,
c: c
};
return myStuffFunctions[functionToCall]();
}
...
}
Seems redundant though. :/
The error is being reported by the import/namespace rule in the eslint-plugin-import plugin. It's occurring because you are deciding which imported function will be called at runtime:
stuffFunctions[functionToCall]();
The plugin's static analysis cannot verify that this is a valid import and it reports it as an error.
The simplest solution would be to add an ESLint comment to reconfigure the rule to allow computed references:
/*eslint import/namespace: ['error', { allowComputed: true }]*/
import * as stuffFunctions from './stuff-functions'
export default class someReactClass {
myFunc(functionToCall) {
return stuffFunctions[functionToCall]();
}
...
}

Categories