Type 'Partial' cannot be assigned a value when combining interfaces with generic types

Consider the following scenario:

class Table<ValuesType extends DefaultTableValues = DefaultTableValues>{
    public values: ValuesType;
    constructor(initialValues:ValuesType) {
        this.values=initialValues;
    }

    public set(newValues:Partial<ValuesType>){
        this.values={
            ...this.values,
            ...newValues
        }
    }
}

class User<MoreValues extends UserValues = UserValues> extends Table<MoreValues>{
    constructor(values:MoreValues) {
        super(values);

        this.set({avatar:'some-string'});
        //ERROR - Argument of type {avatar:'some-string'} is not assignable to type Partial
    }
}
interface DefaultTableValues{
    id:string;
}
interface UserValues extends DefaultTableValues{
    avatar:string;
    username:string;
}

An error occurs when using this.set with the message:

Argument of type {avatar:'some-string'} is not assignable to type Partial

Changing

class User<MoreValues extends UserValues = UserValues> extends Table<MoreValues>
to
class User extends Table<UserValues>
solves the issue, but it limits passing specific User types and extending the User class.

Is it expected for MoreValues to always include the avatar:string property as it extends UserValues?

This situation seems related to this question on Stack Overflow, but finding a solution for my case remains elusive.

Answer â„–1

The issue you are pointing out is indeed similar to the one mentioned in the linked question. The accepted answer from that question states:

Subtyping goes beyond just adding extra properties—it can involve narrowing down the range of acceptable values for those properties.

To illustrate, consider the following interface:

interface RestrictedValues extends UserValues {
    avatar: "nonexistent"
}

This interface extends UserValues, making it compatible with MoreValues. However, the avatar property within this interface is limited to only having the value nonexistent. Therefore, when using the Partial<> type as the first argument for the set() function, it should specifically allow the value nonexistent, not any arbitrary string as implied by UserValues. For example, consider the code snippet below:

class User<MoreValues extends UserValues = UserValues> extends Table<MoreValues>{
    constructor(values: MoreValues) {
        super(values);

        const thing1: RestrictedValues = { avatar: "nonexistent", id: "", username: "" };
        const thing2: MoreValues = thing1;
    }
}

In this scenario, thing1 cannot be directly assigned to

thing2</code because there is no guarantee that <code>MoreValues
will always be instantiated with a value such as { avatar: "" }. If MoreValues allows other subtypes besides RestrictedValues, TypeScript generates the error:

Type 'RestrictedValues' is not assignable to type 'MoreValues'.
  'RestrictedValues' meets the constraints of 'MoreValues', but 'MoreValues' may receive a different subtype than 'UserValues'.

A simpler demonstration of this concept involving boolean values is presented in this answer, which provides further clarity on this matter.

The error indicates that your Generic Type P cannot be assigned a value of {} because P may adhere to a more specific or restricted type that conflicts with the default value.

This means that an empty object {} may not satisfy all the potential types used by Generic Type P.

Let's consider a simpler example focusing solely on boolean values for better comprehension:

interface OnlyBoolIdentityInterface<T> {
  (arg: T): T;
}

function onlyBoolGeneric<T extends boolean>(arg: T = false): T {
  return arg;
}

If we define a type more nuanced than simply a boolean, for instance:

type TrueType = true;

and specialize the function OnlyBoolIdentityInterface to accept only true values like so:

const onlyTrueIdentity: OnlyBoolIdentityInterface<TrueType> = onlyBoolGeneric;

Even though TrueType adheres to the constraint enforced by T extends boolean, the default value arg: T = false does not align with TrueType.

This discrepancy is what the error message aims to convey.

So how can you rectify such errors? Here are some approaches:

  1. Omit the default value
  2. Ensure that T encompasses the specialized type of the default parameter (in this case, false)
  3. Directly align T with parameters utilizing default values

For additional insights into this error message, refer to the corresponding issue: https://github.com/Microsoft/TypeScript/issues/29049.

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

A TypeScript function that returns a boolean value is executed as a void function

It seems that in the given example, even if a function is defined to return void, a function returning a boolean still passes through the type check. Is this a bug or is there a legitimate reason for this behavior? Are there any workarounds available? type ...

Selecting an option with a specific index in Angular 2 RC2

I have encountered a situation where the select options are non-unique, with the same value representing different things. This is how our data is structured and I need to work within those constraints. <select id="mySelect"> <option value = "1 ...

What are the steps to resolve the "EADDRINUSE: address already in use :::3000" error in an integration test?

While testing my simple endpoint using jest and superTest in my TypeScript project, I encountered the listen EADDRINUSE: address already in use :::3000 error. The file app.ts is responsible for handling express functionalities and it is the one being impo ...

Error in TypeScript: The property 'data' is not found within type '{ children?: ReactNode; }'. (ts2339)

Question I am currently working on a project using BlitzJS. While fetching some data, I encountered a Typescript issue that says: Property 'data' does not exist on type '{ children?: ReactNode; }'.ts(2339) import { BlitzPage } from &q ...

Setting up eslint for your new react project---Would you like any further

I am currently working on a TypeScript-based React application. To start off, I used the following command to create my React app with TypeScript template: npx create-react-app test-app --template typescript It's worth noting that eslint comes pre-co ...

Can ES6 class getters, setters, and private properties be utilized in TypeScript with an interface?

I'm currently using TypeScript and trying to figure out how to implement an interface in a class that utilizes ES6 getters and setters. Is it even possible? When I use the code below, errors are highlighted in the class. For instance: (property) S ...

When a variable is used in Postgresql, the ORDER BY clause is disregarded, but accurate results are returned when the variable value is

After investigating, it seems that the query is always returning rows ordered by id, regardless of the value passed in the sortType variable (verified in console). export async function fetchAnimalList(sortType) { noStore(); try { const areas = aw ...

Unable to send a function as props to a child component in TypeScript

Within my application, I have a parent component that holds a state and a setState function. This state and function are then passed down to a child component in order to retrieve values (such as input field data). When the function is triggered in the chi ...

Error encountered while building with Next.js using TypeScript: SyntaxError - Unexpected token 'export' in data export

For access to the code, click here => https://codesandbox.io/s/sweet-mcclintock-dhczx?file=/pages/index.js The initial issue arises when attempting to use @iconify-icons/cryptocurrency with next.js and typescript (specifically in typescript). SyntaxErr ...

Creating an enumeration within a class

I'm encountering difficulties when trying to declare an enum element within a class. Despite attempting various methods to declare the enum, I am unable to make it function properly. Here is the (non-functional) class: export class Device extends El ...

Setting nodeIntegration to false led to an Uncaught ReferenceError: require is not defined when trying to access Object.url (external "url":1) in the electron-react-typescript environment

After setting nodeIntegration to false, I encountered the following error message: "Uncaught ReferenceError: require is not defined at Object.url (external 'url': 1)". Upon clicking on the link referring to "external 'url': 1", it led ...

Create and export a global function in your webpack configuration file (webpack.config.js) that can be accessed and utilized

Looking to dive into webpack for the first time. I am interested in exporting a global function, akin to how variables are exported using webpack.EnvironmentPlugin, in order to utilize it in typescript. Experimented with the code snippet below just to und ...

How to dynamically inject HTML content from a child component into a different component using Angular 5

Is it possible to customize the content of a reusable header section based on the current route data in Angular? The header currently displays a title and description pulled from the route data property. My concern is how to dynamically inject different H ...

Tips for integrating tsconfig with webpack's provide plugin

In my project, I have a simple component that utilizes styled-components and references theme colors from my utils.tsx file. To avoid including React and styled-components in every component file, I load them through WebpackProvidePlugin. Everything works ...

Angular: Issue encountered while attempting to differentiate an '[object Object]'. Arrays and iterables are the only permissible types for this operation

I encountered the following error message while attempting to retrieve updated data: Error trying to diff '[object Object]'. Only arrays and iterables are allowed Snippet of Get Code: allDatas allData(data) { this.allDatas = data } Up ...

When trying to access a certain class property, I was met with the following error message: TypeError: Unable to read/set property 'x' of

Lately, I've delved into the realm of JavaScript / TypeScript and decided to create a basic React App using TypeScript. Within one of my components, I aim to switch between different components using a "state" (where each component will follow the pre ...

issues arise post-transpilation with creating errors

In order to practice, I decided to create a basic TypeScript project. If it could be helpful, here is my ts.config: { "compilerOptions": { "target": "es2016", "module": "commonjs", "outDir": "./dist", "esModuleInterop": true, "forceC ...

Is it feasible to restrict a generic type using typeguard?

I'm currently working on refining a generic function, where the autocomplete feature recognizes that it's encountering a typeguard, preventing it from revisiting the same code block. I suspect that the issue lies in not restricting the type to th ...

Utilizing Angular Services to Share Events and Reusing Components Multiple Times on a Page

My unique custom table is made up of multiple components, each emitting events using a shared service called TableEvent. These events are subscribed to by a class named TableTemplate, which facilitates communication among the different components of the ta ...

Asynchronously download static images with the power of NextJS and TypeScript integration

I have a query regarding my website development using NextJS and TypeScript. The site features a showcase gallery and is completely static. Currently, the initial view shows thumbnails of images. When clicking on a thumbnail, the original image is display ...