Encountering issues with `Partial<this['someProperty']>` usage in TypeScript

Provided

class A {
    props: {
        bool?: boolean,
        test: string
    } = {
        test: 'a'
    };
    setProps(newPropertiesr: Partial<this['props']>) {

    }
    a() {
        this.setProps({
            bool: false
        });
    }
}

An error is encountered

The argument { bool: false; } cannot be assigned to the parameter of type

Partial<this["props"]>
.(2345)

You can see the issue here: here in TypeScript Playground

If the A.props property is defined as {bool?: boolean, test?: string} with test being optional, it works fine. It seems like the Partial<> is being disregarded.

Is there a way to make the Partial function properly with this?


The above scenario illustrates a basic case, for better understanding: I have numerous classes with properties that extend from a main class containing a setProps method and I want to correctly type that inherited setProps.

class Parent {
    props: any;
    setProps(newData: Partial<this['props']>) {/*...*/}
}
class A extends Parent{
    props: {
        bool?: boolean,
        test: string
    } = /* ... */;
    a() {
        this.setProps({
            bool: false
        });
    }
}

Answer №1

Revision #2: Perhaps you might find another approach more fitting for your needs. The code below showcases the implementation of the Parent class as a generic one that accepts the interface of the properties (in this case, PropsA) from an extended class (in this case, A).

class Parent<T> {

    props: T;

    constructor(props: T) {
        this.props = props;
    }

    setProps(props: Partial<T>) {
        Object.assign(this.props, props);
    }
}

interface PropsA {
    bool?: boolean;
    test: string;
}

class A extends Parent<PropsA> {

    constructor() {
        super({ test: 'A' });
    }

    a() {
        this.setProps({
            bool: false,
            // Yields error:
            // nonExistingProperty: true
        });
    }
}

const obj = new A();
console.log(obj.props); // { test: 'a' }

obj.setProps({ test: 'foo', bool: true });
console.log(obj.props); // { test: 'foo', bool: true }

obj.setProps({ test: 'foo' });
console.log(obj.props); // { test: 'foo', bool: true }

obj.a();
console.log(obj.props); // { test: 'foo', bool: false }

// Yields error:
// obj.setProps({ test: 'foo', nonExistingProperty: true });

Instead of using an interface, something like

class A extends Parent<{ bool?: boolean; test: string;}> { ...
could also be viable. However, I personally believe that an interface makes more sense in this context.

Revision #1: I've dabbled with ThisType a bit. While uncertain of its benefits, it may be worth considering:

type Descriptor<T, P> = ThisType<T> & Partial<P>;

class A {
    props: {
        bool?: boolean,
        test: string
    } = {
        test: 'a'
    };
    setProps<T = Descriptor<this, this['props']>>(newProps: T) {
        Object.assign(this.props, newProps);
    }
    a() {
        this.setProps({
            bool: true
        });
    }
}

const obj = new A();
console.log(obj.props); // { test: 'a' }

obj.setProps({ test: 'foo', bool: true });
console.log(obj.props); // { test: 'foo', bool: true }

Original solution: Consider using Partial<A['props']>:

class A {
    props: {
        bool?: boolean,
        test: string
    } = {
        test: 'a'
    };
    setProps(newProps: Partial<A['props']>) {
        // Initial assignment
        Object.assign(this.props, newProps);
    }
    a() {
        this.setProps({
            bool: false
        });
    }
}

The error might be related to the usage of this.

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

Hold off until the operation finishes executing and then deliver Angular 6

Is there a way to delay the subscribe function until my logic is complete and the transform method has updated the keys object? transform(value: any, args:string) : any { let keys = []; this.http.get('src/app/enum-data/enum.json').subsc ...

How to Validate Ionic 2 Radio Button Selections with TypeScript

Imagine having a list like the one shown below: <ion-list radio-group [(ngModel)]="autoManufacturers"> <ion-list-header> Auto Manufacturers </ion-list-header> <ion-item> <ion-label>Cord</ion-label> &l ...

Using Angular i18n to create dynamic forms from an array of objects

After receiving an object from the API, I created a form using an array of objects in TypeScript. Although the form is rendered correctly, it fails to translate when I try to localize the application. import { SpecializedAreasComponents } from 'src/a ...

Managing form input in Ionic2 components from external sources in Angular2

Hello there, I am currently facing an issue with managing form validation along with proper styling for nested forms. Here's what I'm aiming to achieve: I have a Page that displays Tabs components with four tabs. Each tab represents a separate @ ...

Develop a universal function for inserting information into an array within a data set

I need assistance with my Typescript code. I am currently working on a method that pushes data into an array in a mongoose collection. However, the issue I'm facing is that the value is not being passed dynamically to the Key field in the $set operato ...

Create a custom class that functions similarly to a dictionary

Is it not feasible to achieve this? interface IMap { [key: string]: string; } class Map implements IMap { public foo = "baz"; } But instead of success, I encounter the error: TS2420:Class 'Map' does not correctly implement 'IMap& ...

Utilize the identical function within the reducer for numerous mat-slide-toggle and checkboxes in component.html

I'm currently diving into the world of Angular and ngrx while tackling a project focused on enabling users to create forms. In this project, users can add various form elements (such as labels, text fields, dropdown menus, checkboxes, etc.) from a sid ...

Prisma causing a compiler error

Currently, I am in the process of developing a project that integrates a GraphQL server and utilizes Prisma to establish a connection with the database. Additionally, I have chosen to implement this project using TypeScript. Unfortunately, as I compile my ...

What could be causing the issue with my output not displaying correctly?

Hey guys! I'm working on creating a to-do list but I've encountered a problem. Whenever I enter a value in the text field, it doesn't get added to the array of list elements. Strangely enough, when I console.log it, it seems to work. Can any ...

I am looking to transfer information from Angular 4 to Java servlet (cross-domain)

Having trouble sending data from Angular 4 to a Java servlet due to access control restrictions. Need to figure out how to properly insert data into the database using the Java servlet. Here is my code snippet: import { Injectable } from '@angular/ ...

Is there a way to prevent IntelliJ from creating .js files when working with .ts source code?

Working on a mixed Java/Typescript project with Maven as the build tool, I utilize the frontend-maven-plugin to successfully build from the command line. However, I am encountering an issue with IntelliJ 2018.2 where it keeps transpiling .js files for my . ...

What is the best way to categorize variables?

How can I organize variables together: export let findbyc$: Observable<Object>; export let findbyi$: Observable<Object>; export let findbyo$: Observable<Object>; export let findbyob$: Observable<Object>; I would like to group them ...

A guide on specifying the data type for functions that receive input from React Child components in TypeScript

Currently, I am faced with the task of determining the appropriate type for a function that I have created in a Parent Component to retrieve data from my Child Component. Initially, I resorted to using type: any as a solution, although it was not the corr ...

Angular 6 - The requested resource does not have the necessary 'Access-Control-Allow-Origin' header

I am currently working on an Angular 6 project that includes a service pointing to server.js. Angular is running on port: 4200 and Server.js is running on port: 3000. However, when I try to access the service at http://localhost:3000/api/posts (the locat ...

The issue of not displaying the Favicon in Next.js is a common problem

I am currently using Next.js version 13.4.7 with the App directory and I am facing an issue with displaying the favicon. Even though the favicon image is located in the public folder and in jpg format, it is not being displayed on the webpage. However, w ...

NextJS - The server attempted to execute the find() function, which is only available on the client side

When attempting to utilize the .find method within the server component, I encounter an error. export async function TransactionList() { const transactions = await fetch('/transactions'); return ( <ul> {transactions.m ...

Is there a way to determine if silent login is feasible with adaljs-angular4?

I'm currently utilizing the library [email protected] for an Angular 6 project. I am attempting to achieve the following: If a silent login (login without requiring user input) with Office365 is achievable, then perform a silent login (using ...

Stop any ongoing search requests in Angular 7 using Ng2SmartTable

My current setup involves Angular version 7.0.1 and ng2-smart-table version 1.4.0. The issue I'm facing is that each search within the table triggers a new API request to fetch data. What I actually want is for only the latest search request to be pro ...

What causes the "Error: method not allowed" message to appear when attempting to send a "DELETE" request from a Next Js component? (The POST method is

This is my first time on this platform, and I'm currently following a tutorial from Javascript Mastery to create a clone of a thread application. After watching the entire video and building the basic functionality based on it, I decided to enhance th ...

Submit information by utilizing' content-type': 'application/x-www-form-urlencoded' and 'key': 'key'

Attempting to send data to the server with a content-type of 'application/xwww-form-urlencode' is resulting in a failure due to the content type being changed to application/json. var headers= { 'content-type': 'applica ...