Describing this as a function parameter/return type in Typescript

I am looking to create a function that can reference the current object's type in its parameter and return types, like so:

inside .d.ts:

interface Object {
    add(object: Partial<this>): this;
}

within .js:

Object.prototype.add = function(object) {
    Object.assign(this, object);
}

The purpose of this function is to only accept properties for the parameter that are already defined on the object using Partial<this>. However, when attempting to use it like this:

document.body.style.add({
    fontSize: "12px"
});

TypeScript throws an error:

Argument of type '{ fontSize: string; }' is not assignable to parameter of type `Partial<Object>`.
Object literal may only specify known properties, and 'fontSize' does not exist in type 'Partial<Object>'.

I believe this issue arises because the this in my .d.ts refers to Object and not recognizing the proper type such as CSSStyleDeclaration for document.body.style. How can I achieve a function like this, which utilizes the object's type for parameters/return types? Is this attainable in TypeScript?

Answer №1

Just a heads up: making modifications to native prototypes like this is typically frowned upon in the programming community. While you may have your reasons for doing so in certain scenarios, it's generally advised to steer clear of this practice. Nevertheless, let's continue.


Upon closer inspection, it seems that the polymorphic this type doesn't quite align with your expectations when it comes to native interface types such as Object, String, and others. Even recognized subtypes of Object will interpret this as just Object rather than the specific subtype.

To work around this issue, one workaround is to create a generic method with a generic this parameter:

interface Object {
  add<T>(this: T, object: Partial<T>): T;
}

Now, by calling the add() method on an object of type CSSStyleDeclaration, the type checker will automatically infer T as

CSSStyleDeclaration</code, expecting a <code>Partial<CSSStyleDeclaration>
as its argument. This results in the following behavior:

document.body.style.add({
  fontSize: "12px"
});
// (method) Object.add<CSSStyleDeclaration>(
//   this: CSSStyleDeclaration, object: Partial<CSSStyleDeclaration>
// ): CSSStyleDeclaration

Here's a playground link to try out the code yourself!

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

Suggestions for managing the window authentication popup in Protractor when working with Cucumber and TypeScript?

I'm a beginner with Protractor and I'm working on a script that needs to handle a window authentication pop-up when clicking on an element. I need to pass my user id and password to access the web page. Can someone guide me on how to handle this ...

Tips for sending a model as a string in Angular 2

Example (DOM): <div *ngFor="let item of items"> <span [innerHtml]="item"></span> </div> Example (Controller): let items = []; let timer = 60; setInterval(() => timer--, 1000); items.push("This is a dynamic selection WITH a ...

creating a custom type with enums in Angular can lead to implicit 'any' issues

Why does the key of [type] require a type? It may sound strange, but I am facing an issue. Here is some example data: export enum ENUM_Bike { suzuki = 'suzuki', yamaha = 'yamaha', kawasaki = 'kawasaki' } export type T ...

Obtain detailed stack trace information using node-pg for enhanced troubleshooting

Currently, I am implementing node-pg in conjunction with TypeScript. In order to utilize pooling, I have implemented a getPool function following the documentation at export const getPool = (config?: PoolConfig) => { const pool = new Pool(config); ...

MongoMemoryServer - Dealing with Unexpected Errors

Currently, I am conducting tests on a typescript express-mongoose app using jest, supertest, and mongo-memory-server. Interestingly, all the tests are passing successfully, but an error keeps popping up in every test involving mongo-memory-server. It see ...

A step-by-step guide to showcasing dates in HTML with Angular

I have set up two datepickers in my HTML file using bootstrap and I am attempting to display a message that shows the period between the first selected date and the second selected date. The typescript class is as follows: export class Datepicker { ...

What is the role of the 'type' attribute in a button element

I am in need of a customized button that can optionally receive a type attribute: export interface ButtonProps { children: React.ReactNode; onClick?: (e: React.MouseEvent<HTMLElement>) => void; type: ?? } export const Button: React.Functio ...

Changing the button class during an event in Angular 4

In the process of creating an MCQ test, I am looking to implement a feature where selected button options are highlighted in green upon clicking. While I have successfully implemented this feature using Angular 1, I am facing challenges in converting it to ...

Supertest and Jest do not allow for sending JSON payloads between requests

Below is the test function I have written: describe("Test to Create a Problem", () => { describe("Create a problem with valid input data", () => { it("Should successfully create a problem", async () => { const ProblemData = { ...

What will be the output of this typescript function?

Whenever I hover over the keyword 'function', this cryptic description pops up: "(local function)(this: any, next: (err?: mongoose.CallbackError | undefined) => void): Promise<void>" I'm confused about whether it return ...

Adding a custom property to a React component

Currently, I am facing an issue while attempting to modify an MUI component. Everything works smoothly until I execute the build command, at which point it fails. I have experimented with a few variations of this, but essentially I am looking to introduce ...

Tips for creating a versatile function in TypeScript that accepts either a single value or an array of values for two parameters

I'm currently working on a task to develop a versatile function that accepts a parameter called hashMapName, another parameter called 'keys' which can be either a string or an array of strings, and a callback function that will return either ...

How can data be typically encapsulated within Pinia stores when leveraging the composition API?

Currently, in my Vue 3 application with Pinia, I am interested in leveraging the composition API within my Pinia stores. Take a look at this example store: export const useMyStore = defineStore("my", () => { const currentState = ref(0); return ...

Issue: The keyword in React/React-Native is returning a boolean value instead of the expected element object

I've recently delved into learning and coding with React, and I'm encountering a bug that I need help fixing. The issue lies within my application screen where I have two checkboxes that should function like radio buttons. This means that when on ...

Harnessing the power of external Javascript functions within an Angular 2 template

Within the component, I have a template containing 4 div tags. The goal is to use a JavaScript function named changeValue() to update the content of the first div from 1 to Yes!. Since I am new to TypeScript and Angular 2, I am unsure how to establish comm ...

Establishing a pre-commit hook for Husky to utilize Prettier in Angular applications

I am referring to a tutorial on how to set up a Husky pre-commit hook for Prettier in a new Angular project. I want the project files to be automatically formatted to match the committed files, but it seems like something may be missing. The tutorial sugg ...

How to use TypeScript to filter arrays with multiple dimensions

I've been attempting to filter an array with multiple filters, but I can't seem to achieve the desired outcome so far. This is my Angular component: list = [ {type: type1, code: code1}, {type: type2, code: code2}] searchElement(code?: string, ...

What is the process for incorporating TypeScript types into a JavaScript library?

After adding p5 and @types/p5 to my project, I imported p5 in the following way: import * as p5 from 'p5' However, when I tried using p5.createImage(100, 100), I encountered this error message indicating that 'createImage' is not a re ...

Developing a TypeScript library for versatile features across multiple projects

My goal is to export multiple classes, some independent and others interdependent, encapsulated within a single namespace, in the form of a module for external project utilization. To achieve this, I have configured a webpack build to compile these classe ...

Setting compilerOptions.paths is not allowed as alias imports are not supported

Seeking a solution to escape the chaos of relative paths in my React App based on Create-React-App. After referencing this helpful Stack Overflow thread, I updated my tsconfig.json file as follows: { "compilerOptions": { "baseUrl" ...