Looking to bring Victor.js into your TypeScript project?

Struggling to incorporate the victor.js library into a TypeScript project (3.0.1) is giving me quite the headache. Despite installing it from npm along with its typings (victor @types/victor), I am unable to successfully import and use it. Various attempts have been made, but I cannot seem to correctly import it while also resolving types in my IDE.

I've experimented with these methods:

import { Victor} from 'victor';  
import * as v from 'victor'; 

(This module can only be referenced with ECMAScript imports/exports by turning on the 'allowSyntheticDefaultImports' flag and referencing its default export)

import Victor = require('victor');  

(functions, but compatibility issues arise when targeting ECMAScript modules)

const Victor = require("victor");  

(Allows for valid imports and object construction, yet lacks type definitions)

I'm certain that someone out there has faced a similar dilemma before. For reference, the top of the index.js file of victor contains the line:

exports = module.exports = Victor;

Answer №1

Summarized

Your attempt to utilize victor as if it were an ECMAScript 6 module is incorrect. Two possible solutions are:

  1. Have tsc transform your modules to a format like commonjs, which will handle the necessary connection between victor and your code.

  2. Alternatively, load your application through a module loader that can provide the required integration.

Explanatory Details

With the import you've specified, running the latest version of tsc yields the error:

This module can only be referenced with ECMAScript imports/exports by turning on the 'esModuleInterop' flag and referencing its default export.

Enabling esModuleInterop resolves this issue. Check out the test code I employed:

import Victor from "victor";

const foo = new Victor(1, 2);
console.log(foo.y);

Here's the corresponding tsconfig.json:

{
  "compilerOptions": {
    "esModuleInterop": true
  }
}

The problem stems from the fact that when using import Victor from "victor", you're requesting the value exported through an export default... statement based on ES6 modules syntax. However, no such equivalent exists in victor. Hence, there needs to be something to bridge the gap. Upon compilation, tsc generates the following code snippet:

"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
exports.__esModule = true;
var victor_1 = __importDefault(require("victor"));
var foo = new victor_1["default"](1, 2);
console.log(foo.y);

An essential point to note here is the __importDefault helper function that addresses how TS accesses what a module exports as export default.... For ES6 modules, this process favors correctly structured defaults, while for non-ES6 modules, the helper creates a pseudo-module with the original module's default export.

When targeting ECMAScript modules with this tsconfig.json:

{
  "compilerOptions": {
    "esModuleInterop": true,
    "module": "es6"
  }
}

The resulting emitted code becomes:

import Victor from "victor";
var foo = new Victor(1, 2);
console.log(foo.y);

Omitting the helper function implies reliance on the module loader to replicate the logic integrated by __importDefault. Renaming the file extension to mjs and executing:

$ node --experimental-modules test.mjs

Returns the output:

(node:18394) ExperimentalWarning: The ESM module loader is experimental.
2

In situations involving Node with experimental module support, similar functionality akin to __importDefault is provided.


Mere usage of allowSyntheticDefaultImports sans esModuleInterop shifts the responsibility onto you to ensure another tool within your toolchain fulfills the duties of __importDefault. Compiler offers no assistance in this scenario and lets you progress under the assumption that the task will be handled elsewhere.

Answer №2

While there have been some great answers already provided, I wanted to contribute a shorter response.

Encountered error message:

When attempting to import this module with ECMAScript imports/exports, the 'esModuleInterop' flag must be enabled and its default export referenced.ts(2497)

I faced this issue when transitioning from es5 to es6 (and from javascript to typescript) while converting my own javascript file to typescript.

The import statement was like this import * as File from "./MyFile" in OtherFile.ts .

In MyFile.ts, I had export = {funcName} at the end of the file.

The solution involved removing the = so it became export {funcName} in the MyFile.ts file.

(I hope this explanation helps someone; this is my first attempt at providing an answer for an error or problem)

Answer №3

Experiencing the frustration of debugging errors while attempting to create TypeScript definition files for existing JavaScript modules is all too familiar. After spending a considerable amount of time on this task, I encountered an obstacle that seemed insurmountable:

This module can only be referenced with ECMAScript imports/exports by turning on the 'allowSyntheticDefaultImports' flag and referencing its default export

The specific JavaScript code causing this issue can be found here:

module.exports = class AthenaExpress { ...more code.. }

The tsconfig.json file for the successful compilation/"Working version" 1:

{
  "compilerOptions": {
    "outDir": "dist/",
    "sourceMap": true,
    "noImplicitAny": true,
    "module": "commonjs",
    "target": "es6",
    "jsx": "react"
  },
  "baseUrl": "./src",
  "include": [
    "**/*"
  ],
  "exclude": [
    "node_modules"
  ]
}

The "Working version" of the d.ts file includes some import differences 2:

declare module 'athena-express' {
    import * as aws from "aws-sdk";
    interface ConnectionConfigInterface {
        aws: typeof aws,
        s3: string,
        getStats: boolean
    }
    interface QueryResultsInterface {
        Items: any[],
        DataScannedInMB: number,
        QueryCostInUSD: number,
        EngineExecutionTimeInMillis: number,
        Count: number,
    }

    interface QueryInterface {
        sql: string,
        db: string,
    }

    type QueryResult = QueryResultsInterface

    interface AthenaExpressInterface {
        new: (config: ConnectionConfigInterface) => any,
        query: (query: QueryInterface) => QueryResult,
    }

    class AthenaExpress {
        new: (config: ConnectionConfigInterface) => any;
        constructor(config: ConnectionConfigInterface);
        query: (query: QueryInterface) => QueryResult;
    }
}

A different version of the d.ts file faced the same error, despite enabling esModuleInterop and adjusting module and target attributes. This version had import statement differences 3:

import * as aws from "aws-sdk";
interface ConnectionConfigInterface {
    aws: typeof aws,
    s3: string,
    getStats: boolean
}
interface QueryResultsInterface {
    Items: any[],
    DataScannedInMB: number,
    QueryCostInUSD: number,
    EngineExecutionTimeInMillis: number,
    Count: number,
}

interface QueryInterface {
    sql: string,
    db: string,
}

type QueryResult = QueryResultsInterface

interface AthenaExpressInterface {
    new: (config: ConnectionConfigInterface) => any,
    query: (query: QueryInterface) => QueryResult,
}

declare class AthenaExpress {
    new: (config: ConnectionConfigInterface) => any;
    constructor(config: ConnectionConfigInterface);
    query: (query: QueryInterface) => QueryResult;
}

export = AthenaExpress

notes:

The location of the definition file and the related file I was trying to work with:

 tree src/backend/js
    src/backend/js
        ├── athena-express.d.ts
        └── helloworld.ts
  1. "Working Version" refers to when tsc compiled without errors.
  2. In helloworld.ts
    import {AthenaExpress} from  "athena-express";
  3. In helloworld.ts
    import * as AthenaExpress from "./athena-express";

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The customer opts to store all images indefinitely into the data stream

I have set up a node server that captures images from a webcam at regular intervals and sends them to the client using the Delivery.js node module. Upon monitoring the browser resources in Chrome development tools, it appears that each image sent is being ...

Differences between ts-loader and babel-loader when working with TypeScript in webpack

Recently, I set out to compare the compiled output code between these two configurations. ts-loader { test: /\.tsx?$/, use: 'ts-loader', } babel-loader use: { loader: 'babel-loader', options: { p ...

What is the process for organizing a table column with the use of a <select> tag?

My goal is to implement column sorting in a table. I've managed to sort the columns by clicking on the table header using jQuery (e.g., `$('th').click(function(){ )`, but I'm struggling to achieve the same functionality using select opt ...

What is the process for bundling an NPM package that contains an index file located at the package's root?

Exploring the Concept of "Barrel" Modules and NPM Package Publishing A concept known as a "barrel" is used to re-export modules within an index.ts file in order to streamline imports and organization. This technique allows for importing modules from a fol ...

Error encountered while attempting to inject a store into a React application using Typescript

Currently, I am working on building a React app with TypeScript and using Redux for state management. However, I encountered an error related to the app component. https://i.sstatic.net/zetyR.png -app.tsx import React from 'react'; import { Pro ...

What could be causing the frontend to receive an empty object from the express server?

Struggling to understand how to execute this request and response interaction using JavaScript's fetch() along with an Express server. Here is the code for the server: var express = require('express'), stripeConnect = require('./r ...

How can Codeception/Selenium help in testing the tooltip or customValidity message?

I am trying to implement a feature in my Codeception scenario where I want to validate a form submission with user errors, such as confirming a wrong email address, and display a custom tooltip message in the browser. HTML <form ... > <label ...

How come the props aren't being passed from the parent to the child component? (React / TypeScript)

Learning TypeScript for the first time and facing an issue with passing props from parent to child components. The error seems to be related to the type of props, but I'm not sure how to fix it since all types seem correct. Error message: "Property ...

Find an object within a nested object that meets a specific condition

When given an object structure like the one below: temp = [ {category: 'category1', branch: [{key: 'key A1', value: 'value A1'}, {key: 'key B1', value: 'value B1'}] }, {category: 'category2', ...

Issue with Angular 2: Unable to display 404 error page

I have created a custom "404 - page not found" page to handle situations where the user enters a URL that does not match any paths in my web app: export const routerConfig: Routes = [ { component: LandingPageComponent, path: "", }, { ...

Node.js HTTP request not returning any content in the body/message

Having some trouble with the requestjs package as I attempt to post data and receive a response. No matter what I do, the body response always ends up being undefined. const request = require('request'); request({ method: "POST", ...

What is the best approach for implementing Vuex with TypeScript?

My research on the topic has primarily led me to this informative article. I am currently working on setting up a store with 2 modules. export interface RootState { /** root state props **/ } const store: StoreOptions<RootState> = { module ...

Assigning to a constrained type with an indexable signature results in failure

When using typescript 4.7.2, I encountered an issue where the following code fails only when assigning a value: type IndexableByString = { [k: string]: any }; function test<T extends IndexableByString>(target: T, key: string) { var prop = target ...

Prevent vertical axis rotation in OrbitControls with THREE.js

In my three.js project, I have a scene with OrbitControls that allows me to rotate the camera around the origin at position 0,0,0. I am attempting to restrict the camera rotation to only rotate vertically along the y-axis infinitely (up or down). You can ...

Loading textures for cubes using Three.js TextureLoader and CubeGeometry

I am currently learning threejs and I am trying to apply 6 different textures to each side of a cube. I initially achieved this using loadTexture. var material3 = new THREE.MeshPhongMaterial( {map: THREE.ImageUtils.loadTexture('textures/ps.png') ...

Retrieve the overall number of Formik errors for a specific field array

In the given Yup validation setup below, there is a nested Formik FieldArray: parentLevel: Yup.array().of( Yup.object({ childrenLevel: Yup.array().of( Yup.object({ childName: Yup.string().required('Name is required') ...

Expanding Text Box

My goal is to create a textarea that automatically adjusts its size as the user types or pastes long text into it. This is my current implementation. class AutoResizeTextArea extends InputBase { render() { const { label, placeholder, wrap, ro ...

Retrieve a live variable from an external JavaScript file

I'm currently working with an external file that showcases videos on my website using a unique URL with a token and expiration date. Here's an example: https://www.thevideositeurl.com/embed/231231/ To include this video on my page, I use the fo ...

Assigning values to objects based on the types of their properties in Typescript

In my Redux store, I want to create a reducer that can modify any attribute values within the store. Consider the state object defined with specific types: type StoreState = { admins: Admin[]; messages: Message[]; pageInformation: PageInformation; } ...

Refreshing a page occurs every 30 seconds or upon the user submitting a form

My PHP page consists of various includes for different sections of a video website. One of these sections is a comments area where users can submit their feedback to a database successfully. However, I want to ensure that only the specific included page/di ...