Expanding Arrays in TypeScript for a particular type

There is a method to extend arrays for any type:

declare global {
  interface Array<T> {
    remove(elem: T): Array<T>;
  }
}

if (!Array.prototype.remove) {
  Array.prototype.remove = function<T>(this: T[], elem: T): T[] {
    return this.filter(e => e !== elem);
  }
}

Source: Extending Array in TypeScript

But now the question arises, is it possible to extend the array only for a specific type?. For example, only for arrays of type User -> Array<User>.

I aim to introduce an extension method, like .toUsersMap(), which will only be accessible for arrays containing items of type User.

Answer №1

You can replicate similar functionality:

type Person = {
  tag: 'Person'
}

interface Array<T> {
  toPeopleMap: T extends Person ? (elem: T) => Array<T> : never
}

declare var person: Person;

const personsArr = [person]

personsArr.toPeopleMap(person) // valid

const someOtherArray = [{ notPerson: true }]

someOtherArray.toPeopleMap() // Cannot call this expression

If the T parameter does not extend the Person type, TypeScript will prevent using the toPeopleMap method.

Try it out here

Answer №2

Suppressing the IntelliSense prompting for toUsersMap() on Arrays may not be feasible, but you can enforce a compiler error when calling arr.toUsersMap() unless arr is of type Array<User>. One method to achieve this is by incorporating a this parameter in the toUsersMap() method:

interface Array<T> {
  toUsersMap(this: Array<User>): Map<string, User>;
}

Now, the compiler will mandate that toUsersMap() can only be invoked with a this context referring to something assignable to Array<User>:

interface User {
  username: string;
}
const arr = [{ username: "foo" }, { username: "bar" }];
arr.toUsersMap() // No error, works fine

const another_array = ["hello", 123];
another_array.toUsersMap() // Error occurs
//~~~~~~~~~~~ <--
// The 'this' context of type '{ notUser: boolean; }[]' is 
// not compatible with the method's 'this' of type 'User[]'

Link to Playground with 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

How to assign keys and values to array elements in PHP

Trying to accomplish a simple task of adding a key and value to each index of an array. Example array: [0] => Array ( [student_id] => 1 [class_id] => 1 [student_grno] => 11198 [student ...

What is the best way to retrieve all SVG objects within a specific area in an Angular application?

I am currently developing an SVG drawing application and have implemented a tool that enables users to select all shapes within a rectangular area. However, I am facing the challenge of detecting the SVG shapes located underneath the selected rectangle. ...

Is it possible to combine TypeScript modules into a single JavaScript file?

Hey there, I'm feeling completely lost with this. I've just started diving into Typescript with Grunt JS and I could really use some assistance. I already have a Grunt file set up that runs my TS files through an uglify process for preparing the ...

Implement Google Apps Script Array in HTML form for autocompleting datalist suggestions

I have successfully created a Google Scripts function that generates an array from a column in a Google Sheet by filtering out any spaces. However, I'm facing a challenge in figuring out how to pass this variable to my HTML form so that I can set up a ...

Typescript: Streamline the process of assigning types to enum-like objects

One common practice in JavaScript is using objects as pseudo-enums: const application = { ELECTRIC: {propA: true, propB: 11, propC: "eee"}, HYDRAULIC: {propA: false, propB: 59, propC: "hhh"}, PNEUMATIC: {propA: true, propB: ...

MongoDB NextJS connection issue "tried to retrieve a connection from a closed connection pool"

I am attempting to establish a connection to my MongoDB database in order to retrieve some information. When setting up the connection without fetching any data, everything works fine. However, when trying to fetch data, the console throws this error: at ...

The error code TS2474 (TS) indicates that in 'const' enum declarations, the member initializer must be a constant expression

Error code: export const enum JSDocTagName { Description = "desc", Identifier = "id", Definition = "meaning", } Implementing Angular 6 in conjunction with the .NET framework. ...

Exploring Typescript: Combining types (rather than intersecting them)

Let's analyze the scenario below type MergeFn = <K1 extends string, V1, K2 extends string, V2>( k1: K1, v1: V1, k2: K2, v2: V2 ) => ??? let mergeFn: MergeFn // actual implementation doesn't matter for this question What should b ...

Swap out the default URL in components with the global constant

Could anyone offer some assistance with this task I have at hand: Let's imagine we have a global constant 'env' that I need to use to replace template URLs in components during build time. Each component has a default template URL, but for ...

Typescript libraries built specifically for unique custom classes

I am currently exploring the most effective method for creating a class library in Typescript and deploying it to NPM along with a definitions file. The classes within the library serve as models that are utilized by multiple RESTful services. Some of the ...

How can I integrate keydown.control with a unique click function in Angular?

Is there a way to choose multiple number elements in random order and save them to an array by holding down the control key (CTRL) and clicking on the element? For example, selecting 2 and 4 out of 5. I tried different methods but couldn't figure out ...

Mastering the Art of Utilizing Generic Typing to Access Objects

I am trying to find a way to access an object by class using generic typing. The issue I am encountering is that I am getting an error when trying to check if the locators contain an input field. type '{ form1: { item2: { checkbox: string; input: st ...

Is there an issue with this return statement?

retrieve token state$.select(state => { retrieve user access_token !== ''}); This error message is what I encountered, [tslint] No Semicolon Present (semicolon) ...

Is it possible for me to convert a .map array into a comma-separated array enclosed in double quotation marks?

I am attempting to extract data from a group of twig variables and convert them into a javascript plugin. The data consists of dates listed in an array format. Initially, they are displayed on the template as a string like this: {"date":"2018-08-30, 2018- ...

What is the best way to disable a collapsed section in VS Code using comments?

I'm wondering how to properly comment out a "folded" section of code using VS Code. For instance, I want to comment out the collapsible region: if (a == b) { dance(); } I am familiar with the keyboard shortcut for folding regions: Ctrl + Shift + ...

What could be causing an error with NextJS's getStaticPaths when running next build?

When attempting to use Next.js's SSG with getStaticPaths and getStaticProps, everything worked fine in development. However, upon running the build command, an error was thrown: A required parameter (id) was not provided as a string in getStaticPath ...

The package import path varies between dynamic code generation and static code generation

I have organized the src directory of my project in the following structure: . ├── config.ts ├── protos │ ├── index.proto │ ├── index.ts │ ├── share │ │ ├── topic.proto │ │ ├── topic_pb. ...

Learn the process of seamlessly uploading various document formats, videos, and previewing documents with Angular software

I am having trouble viewing uploaded files in the carousel. While I can see video and image files, other document formats are not displaying. Can someone please recommend a solution to enable viewing all types of documents as well? mydata = [] onSelect ...

What steps can I take to persistently subscribe to SignalR from an Angular service even in the event of connection failures?

Is there a way to safely attempt to connect to SignalR with intervals between attempts until the connection is established? Also, does anyone have advice on how to handle the different stages of connectivity to the web sockets effectively? We are utilizin ...

Troubleshooting Problems with Wordpress Shortcode Arrays

Here is an example of how a shortcode appears: [posts3col ids="249, 318, 93" category="Events"] Below is the code related to the shortcode: add_shortcode('posts3col', 'posts_func'); function posts_func($atts){ extract(shortcode_a ...