Unable to employ a custom Typescript .d.ts file

Currently, I am delving into learning TypeScript and encountering a hurdle while attempting to define a class in a TypeScript definition file and then utilize it in a TypeScript file.

The dilemma lies with a JavaScript "class" called "Facade," which serves as a well-known design pattern of the OpenLayers Library. The structure of this facade looks like this:

lib/carto-facade/OpenLayerFacade.js :

function OpenLayerFacade() {
    this.map =   new ol.Map({
        layers: [
            new ol.layer.Tile({source: new ol.source.OSM()})
        ],
        view: new ol.View({
            center: [43.5, 5.0],
            zoom: 2
        }),
        target: 'map'
    });
}

OpenLayerFacade.prototype.setViewCenter = function(latitude, longitude)  {
    this.map.getView().setCenter(ol.proj.fromLonLat([longitude, latitude]));
}

Subsequently, I wish to employ this facade in a TypeScript project. Consequently, I formulated my .d.ts file as follows:

lib/carto-facade/OpenLayerFacade.d.ts

declare interface OpenLayerfacade {
    setViewCenter(latitude:number, longitude:number):void;
}

declare interface OpenLayerfacadeFactory {
    new(divName:string): OpenLayerfacade;
}

export var OpenLayerfacade:OpenLayerfacadeFactory;

Now, I aim to utilize it in a TS script loaded by a browser:

/// <reference path="../typings/jquery/jquery.d.ts" />
/// <reference path="../lib/carto-facade/OpenLayerFacade.d.ts" />

import oli = require('../lib/carto-facade/OpenLayerFacade');

$(document).ready(function () {
    var ol = new oli.OpenLayerFacade("map");
    ol.setViewCenter(43.5, 6.0);
    console.log("Map displayed");
});

While everything compiles (transpiles) successfully, upon loading my webpage containing the script, I encounter the following error:

Uncaught TypeError: Cannot read property 'OpenLayerFacade' of undefined

This issue arises when I attempt to instantiate a new "OpenLayerFacade".

I have been using require.js, therefore transpile with the option "module": "amd" in my tsconfig.json

The structure of my HTML File is as shown below:

<html lang="en">
...

What could be going wrong?

I believe that the solution to my predicament might lie within the TypeScript Handbook. Any guidance on locating the relevant information would be greatly appreciated.

Kind regards,

Answer №1

When utilizing commonjs, it is essential to have an Ambient External Module definition in place. For detailed information, refer to this documentation: http://www.typescriptlang.org/Handbook#writing-dts-files (§ Ambient External Modules)

To cater to both Internal Modules and External Modules, there exists a method for creating definitions that serve dual purposes. One example could involve defining a class.

//Internal module
declare namespace Oli {
    class OpenLayerfacade {
        constructor(divName:string);
        setViewCenter(latitude:number, longitude:number):void;
    }
}

//External module
declare module "oli" {
    export = Oli
}

Subsequently, import using the new 1.6 syntax

import { OpenLayerfacade } from 'oli'

Answer №2

Here's what the code is doing:

import oli = require('../lib/carto-facade/OpenLayerFacade');

This line means that you are bringing in an external module. However, your JavaScript code is not an external module (you could write it in pure JS if necessary). A simple solution would be to remove that line from your TypeScript code. Instead, make sure that your JS code creates a global variable OpenLayerfacade (as specified in d.ts) during runtime - it's up to you to load the JS code. Then in TypeScript, use the declared global variable.

/// <reference path="../typings/jquery/jquery.d.ts" />
/// <reference path="../lib/carto-facade/OpenLayerFacade.d.ts" />

$(document).ready(function () {
    var ol = new OpenLayerFacade("map");
    ol.setViewCenter(43.5, 6.0);
    console.log("Map displayed");
});

This is how you would handle it without using commonjs - by using internal modules or namespaces.

If you are using commonjs and want to utilize external modules, then your JS code should be a commonjs module (an external module in TypeScript terminology). Additionally, wrap your declaration file in a module to inform the compiler about it.

export modules 'oli' {
    declare interface OpenLayerfacade {
        setViewCenter(latitude:number, longitude:number):void;
    }

    declare interface OpenLayerfacadeFactory {
         new(divName:string): OpenLayerfacade;
     }

    export var OpenLayerfacade:OpenLayerfacadeFactory;
}

and import it in a commonjs manner:

import oli = require('oli');

You still need

/// <reference path="../lib/carto-facade/OpenLayerFacade.d.ts" />

to specify to the compiler where to find the 'oli' module (this can be simplified with tsc >1.6).

If your JS snippet is correct and you don't want or can't convert JS to a commonjs module, you can still integrate it into your application using commonjs. Simply follow the first method described with namespaces.

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

Angular displays [object Object] upon return

I have been struggling to send a post request, but unfortunately the API is returning undefined. When I try to send it to my API, it shows up as [object Object] getAccouting():Observable<any>{ // let json = this.http.get<any>('/assets/ ...

The 'import type' declaration cannot be parsed by the Babel parser

Whenever I attempt to utilize parser.parse("import type {Element} from 'react-devtools-shared/src/frontend/types';", {sourceType: "unambiguous"}); for parsing the statement, I come across an error stating Unexpected token, exp ...

What could cause my arguments to "not align with any signature" of console.log?

Here is a basic class example: export class Logger { constructor(private name: string) {} debug(...args: any[]) { console.debug(...args) } log(...args: any[]) { console.log(...args) } } Despite being able to pass anything to console.l ...

Docz: Utilizing Typescript definitions for props rendering beyond just interfaces

We are currently using Docz to document our type definitions. While it works well for interfaces, we've run into an issue where rendering anything other than interfaces as props in Docz components doesn't seem to display properly. I'm seeki ...

What is the best way to ensure that all function parameters using a shared generic tuple type have a consistent length?

Understanding that [number, number] | [number] is an extension of [number, ...number[]] is logical, but I'm curious if there's a method to enforce the length of tuples based on the initial parameter so that the second tuple must match that same l ...

React is not displaying the most recent value

During the initial rendering, I start with an empty array for the object date. After trying to retrieve data from an influxDB, React does not re-render to reflect the obtained results. The get function is being called within the useEffect hook (as shown in ...

TS interfaces: Understanding the distinction between optional and mandatory properties

In this example, I am demonstrating TypeScript interfaces in a simple way: interface A: { id: number; email: string; } interface B extends A { login: string; password: string; } My goal is to have certain requirements when creating objects fr ...

Utilize generics to define the data type of the output

Within my Angular service, there is a method that retrieves data from Sync Storage: getFromSyncStorage(key: string): Promise<Object | LastErrorType> { return new Promise(function (resolve, reject) { chrome.storage.sync.get(key, function ( ...

Issues with typescript compiler when using React-beautiful-dnd

I recently updated react and react-beautiful-dnd to the newest versions and now I am encountering many type errors in my code: {sortedDimensions.map((dimension: any, index: number) => ( <Draggable key={index} ...

Managing middleware in tRPC: Utilizing multiple methods for a single route call?

We're currently working on a group project with a tight deadline of just a few weeks. Our team has opted to utilize the T-3 stack for this project and have chosen tRPC as the server framework. While I am familiar with express, I am finding it challeng ...

Removing duplicate elements from an array in TypeScript

In my TypeScript code, I am working with an array of objects and need to remove any duplicates. The code below accomplishes this task: const uniqueObjects = Array.from(new Set(nonUniqueObjects.map((x) => { return JSON.stringify(x); }))). ...

Issue with API and Middleware: unable to access /api/auth/providers

Currently, I am following an educational video tutorial on Next Auth V5. Despite being a beginner in coding, I am doing my best to keep up. I am currently stuck at 2 hours, 9 minutes, and 45 seconds into the 8-hour-long video. The issue arises during th ...

What is the process for developing a bespoke TypeScript Declaration library and integrating it into my projects through NPM or GitHub Packages?

Project Description I am currently developing a customized TypeScript type declaration library that will be utilized in various projects. However, I am encountering an issue when it comes to importing this TypeScript library into my projects. Although it ...

Customizing the MUI Select component with TypeScript

What seems to be the issue in this code snippet? TS2322: Type '(event: SelectChangeEvent) => void' is not assignable to type '(event: SelectChangeEvent<unknown>, child: ReactNode) => void'.   Types of parameters 'even ...

Injecting AngularJS together with TypeScript and Restangular to optimize application performance

Encountering an issue while trying to configure my angularjs + typescript application with the restangular plugin Here are the steps I have taken: Ran bower install --save restangular (now I have in index.html <script src="bower_components/restang ...

Issue with TypeScript Functions and Virtual Mongoose Schema in Next.js version 13.5

I originally created a Model called user.js with the following code: import mongoose from "mongoose"; import crypto from "crypto"; const { ObjectId } = mongoose.Schema; const userSchema = new mongoose.Schema( { //Basic Data ...

"Troubleshooting the issue of Angular's select binding causing a disruption

The Angular version being used is 1.4.7. Within the model in question, there are two objects: 'systems', which is an array, and 'selectedSystem'. The desired outcome is for 'selectedSystem' to reference one of the objects wit ...

Determine the route parameter name based on the path string, for example, '/posts/:id'

My Route interface has a params object, and I'm looking to ensure type safety on that params object. For example: If we have a route config like this: { post: { path: 'posts/:id', } } navigate({ name: 'post', params: { wr ...

typescript - instantiate an object using values stored in an array

Assume we have a model defined as follows. export interface Basicdata { materialnumber: number; type: string; materialclass: string; } We also have an array containing values that correspond directly to the Basicdata model in order, like this: ...

Dealing with reactive form controls using HTML select elements

I am working with a template that looks like this: <form [formGroup]="form"> <mdl-textfield type="text" #userFirstName name="lastName" label="{{'FIRSTNAME' | translate}}" pattern="[A-Z,a-zéè]*" error-msg ...