Creating a custom Map and Array declaration in a .d.ts file with Typescript

I am looking to define custom type declarations for the Map and Array classes in a .d.ts file like this:

//customTypes.d.ts

interface CustomMap<U, V> {
    get(key: U): V | undefined;
    set(key: U, val: V): void;
}
interface CustomArray<T> {
    length(): number;
}

My goal is to achieve the following functionality using only declarations in the .d.ts file:

//example.ts

cArray = new CustomArray<number>(1, 3, 2, 3);
cArray[0] = 2;
console.log(cArray[2]); // 2
for (const i of cArray) {
    console.log(i);
}

cMap = new CustomMap<string, string>(['1', 'a'], ['3', 'b'], ['2', 'ç'], ['4', 'd']);
for (const [k, v] of cMap) {
    console.log(k + ':' + v);
}

What modifications should be made to the CustomMap and CustomArray interfaces to achieve this functionality? (using ES2015 or higher).

Answer №1

If you want your sample code to function correctly, you must have declarations that correspond to each line within the code snippet. Let's delve into them:


const cArray = new CustomArray<number>(1,3,2,3);

For this code block to execute properly, you need a value called CustomArray, with its type being a constructor ("newable") signature that accepts a variable list of T values and returns a CustomArray<T> value. This should not be added to the CustomArray<T> interface but should instead be declared as follows:

declare const CustomArray: new <T>(...a: T[]) => CustomArray<T>;

cArray[0] = 2;
console.log(cArray[2]) // 2

In order for these lines to work, the CustomArray<T> interface needs to include a numeric index signature where the values are of type T, like this:

    [n: number]: T;

for (const i of cArray) {
    console.log(i);
}

For this part to operate successfully, the CustomArray<T> interface should be made to be iterable, meaning it has a method titled Symbol.iterator that returns an Iterator<T>:

    [Symbol.iterator](): IterableIterator<T>;

The same modifications need to be applied for your CustomMap to function as intended. Here is how I would expect your declarations to be structured:

//iter.d.ts
interface CustomMap<U, V> {
    get(key: U): V | undefined;
    set(key: U, val: V): void;
    [Symbol.iterator](): IterableIterator<[U, V]>
}
declare const CustomMap: new <U, V>(...a: [U, V][]) => CustomMap<U, V>;

interface CustomArray<T> {
    length(): number;
    [n: number]: T;
    [Symbol.iterator](): IterableIterator<T>;
}
declare const CustomArray: new <T>(...a: T[]) => CustomArray<T>;

With these in place, the following snippets should compile without errors (ensure proper declaration for variables like cArray and cMap):

//test.ts

const cArray = new CustomArray<number>(1, 3, 2, 3);
cArray[0] = 2;
console.log(cArray[2]) // 2
for (const i of cArray) {
    console.log(i);
}

const cMap = new CustomMap<string, string>(['1', 'a'], ['3', 'b'], ['2', 'ç'], ['4', 'd']);
for (const [k, v] of cMap) {
    console.log(k + ':' + v);
}

I hope this clarifies things for you and wish you good luck!

Link to modified code

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

Is there a way to determine the present date within a template?

In my component, I am working with an object that contains a timestamp. What I aim to achieve is to dynamically check this timestamp in the template at runtime. For instance, I want to display the online status of a member by showing a green dot if they a ...

Creating a TypeScript map with conditional items

I encountered an error while trying to add an item conditionally to a Map using .filter, receiving the message Type 'null' is not assignable to type 'readonly [string, Book]'.(2769). This issue seems to arise only when adding items cond ...

Angular2 encountered a TypeError stating that self._el_11 is not a valid function

Looking to attach an event listener to an input field? Check out the code snippet below: <input ref-search (keyup)="search(search.value)"> Here is the corresponding search method: search(condition: string){ console.log(condition); } When ente ...

Having trouble retrieving data in the service. Unable to subscribe to it from other components

userService.ts private APIUrl: string = environment.APIUrl; constructor(private inService: API, private httpClient: HttpClient) { } private _userDataDashboard$ = new ReplaySubject<UserDetailsDashboard>(1); getUserDetailsSubject(): Obser ...

Can we limit a generic type to only accept a subset of keyof values in TypeScript?

In the latest version (2.1) of TypeScript, I have the ability to restrict a method argument in a generic class to be a property of the generic type. class Foo<TEntity extends {[key:string]:any}> { public bar<K extends keyof TEntity>(key:K, ...

Initiating the process of loading a texture atlas using PIXI Js and parcel bundler

I've recently started working with JS programming and pixi JS. I'm attempting to load a texture atlas from a json file following this tutorial module: https://github.com/kittykatattack/learningPixi#spriteproperties For my setup, I am using types ...

Issue with Props Type Check not functioning as expected in Typescript with React

I am utilizing Typescript within my React application. I aim to rigorously verify the type of props being passed to my components and trigger an error if it does not match. import React from "react"; import styles from "./ServiceDetailCard.css"; type Ser ...

What is the process for defining global type aliases in TypeScript?

One of the aliases I use is type ReactMouseEvent = React.MouseEvent<HTMLDivElement, MouseEvent> To implement this alias, I created a globals.d.ts file within the types folder of my project: // in globals.d.ts import React = require('react' ...

Ensuring Typescript Specifies a General Type While Retaining Specific Keys and Values

There are times when using as const at the end of an object declaration can be incredibly helpful, as it creates a literal singleton type. However, the drawback is that you lose the ability to specify a type without sacrificing the specific keys as shown i ...

Display an element in Angular2 when a selection is changed

I am working with Angular 2 and typescript. I have a requirement where I only want to display the Save button if a new option is selected, and then hide the Save button after it is clicked. I'm not sure how to approach this problem. Below is the code ...

Encountering an error while performing a GET request in Angular: Issue arises from inability to locate a differ that supports the object '[object Object]'

The tab1.page.ts is responsible for fetching a list of places through a GET request. Laravel returns the data in JSON format. tab1.page.ts export class Tab1Page implements OnInit { places$: Place[]; constructor( private placesService: PlacesServ ...

Trigger event when ngModel changes

Currently, I am trying to perform a test on a select element... <select [ngModel]="selectedRouters" name="routerName" class="form-control" id="routersSelect" size="12" (ngModelChange)="selectRouters($event)" multiple> <option [value]="route ...

Is the type narrowed by type guards only when true is returned?

It was my understanding that a type guard handling multiple types instanceOfA(arg: A | B | C): arg is A, would narrow the type to either A (if the guard returns true) or B | C (if it returns false) However, in the case of instanceOfB below, when returning ...

Keep the list up-to-date by adding new items promptly

Utilizing Angular 7, I have implemented the following service (Click here for StackBlitz Example): @Injectable({ providedIn: 'root' }) export class TodoService { todos: BehaviorSubject<Todo[]> = new BehaviorSubject([ { id: 1, tit ...

Configuring a NestJS application to establish a TypeOrm connection using environment variables and @nestjs/config

Looking for the best way to set up a NestJS database using a .env file in compliance with legal requirements. The goal is to utilize the @nestjs/config package to import .env variables and incorporate them into the TypeOrmModule. It appears that utilizing ...

Error: Unable to modify a property that is marked as read-only on object '#<Object>' in Redux Toolkit slice for Firebase Storage in React Native

Hey there! I've been working on setting my downloadUrl after uploading to firebase storage using Redux Toolkit, but I'm facing some challenges. While I have a workaround, I'd prefer to do it the right way. Unfortunately, I can't seem to ...

Will the subscription be automatically removed once the value is resolved?

While examining some code, I stumbled upon the following snippet: this.busy = this.service.getInfo().subscribe((info: InfoData[]) => { this.setInfo(info); }); The property busy is defined within a component and of type boolean, it ...

Executing function in component via template

Within the template section <tr *ngFor='let activity of pagedWorkflowActivities' [style.background-color]="setBackgroundColor(activity)"> In the component section setBackgroundColor(activity: WorkflowActivity) { return 'red&apos ...

The image path for "tour-x-b-cover.jpeg" at http://localhost:4200 is broken and the image is not displayed

I am facing an issue with my table list of tours where all the required information is displayed except for the image Cover. Despite checking everything, I cannot seem to figure out why the image path is broken. Initially, I suspected that there might be a ...

Preventing the automatic selection of the initial item in a PrimeNG dropdown menu

While utilizing the p-menu component from PrimeNG in popup mode ([popup]="true"), I encountered an unexpected issue where the first item in the menu is automatically selected and turns gray. Here is the code snippet that I am using: <p-menu #menu [popu ...