'The object literal does not match the type of parameter' error is displayed

Encountering an issue with object literal type.

interface OptionalFoo {
  foo?: number;
}

interface Bar {}

function foobarFn(foobar: OptionalFoo & Bar) {}

foobarFn({ bar: 1 }); // error

foobarFn({ bar: 1 } as { bar: number }); // ok

foobarFn({ bar: 1 } as { bar: 1 }); // ok!

Running into a type error due to object literal with inferred type:

Argument of type '{ bar: number; }' is not assignable to parameter of type 'OptionalFoo & Bar'

The inference itself is not the root cause of the problem:

const bar = { bar: 1 }; // inferred { bar: number; }
foobarFn(bar); // ok!?

A similar issue arises with spread syntax vs Object.assign:

foobarFn({...{ bar: 1 }}); // error

foobarFn(Object.assign({}, { bar: 1 })); // ok!?

Is there a way to achieve the desired behavior with inferred object literal type (excess property check) without using in-place object literals, such as through the use of a variable like bar or a function call like Object.assign({ bar: 1 })?

Answer №1

To clarify, the issue at hand goes beyond just excess property checks. Excess property checks typically come into play when directly assigning an object literal to a location. However, in this case, the unexpected behavior arises when indirectly assigning an object, which would normally pass under excess property checks.

function foo(o: { bar: number }) { }
foo({ bar: 0, foo: "" }) // error with direct assignment
foo({ bar: 0, foo: ""} as { bar: 0, foo: "" }) // okay with indirect assignment

The surprising part, in my opinion, is that another check (the weak type check) fails to catch this error. According to weak type checks, if a type has only optional properties and we attempt to assign a type with no common properties to it, an error should be thrown:

function foo(o: { bar?: number }) { }
foo({ foo: "" }) // error for excess properties: Object literal may only specify known properties, and 'foo' does not exist in type
foo({ foo: ""} as { foo: "" }) // error for weak types: Type '{ foo: ""; }' has no properties in common with type '{ bar?: number; }'.

This seems like a gap in weak type checks. A weak type is defined by having at least one property, all of which are optional, and lacking certain signatures according to this PR. However, in the intersection implementation, all types within the intersection must also be weak for it to qualify as a weak type. As shown in the compiler code:

function isWeakType(type: Type): boolean {
    if (type.flags & TypeFlags.Object) {
       // ....
    }
    if (type.flags & TypeFlags.Intersection) {
        /// All intersection members have to be weak
        return every((<IntersectionType>type).types, isWeakType); 
    }
    return false;
}

Therefore, since interface Bar {} is not considered a weak type due to lacking properties, any intersection involving it will not trigger weak type checking errors. Removing Bar from the intersection would result in errors whenever an object with no common properties is assigned.

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

Using GraphQL to set default values in data within a useEffect hook can lead to never

Here's the code snippet that I'm working with: const [localState, setLocalState] = useState<StateType[]>([]); const { data = { attribute: [] }, loading } = useQuery<DataType>(QUERY, { variables: { id: client && client.id ...

Solution: How to fix the error: Invalid component type, 'Draggable' cannot be used with JSX in react-draggable

I encountered an error while working on this Next.js React project Type error: 'Draggable' cannot be used as a JSX component. Its instance type 'Draggable' is not a valid JSX element. The types returned by 'render()&apo ...

Efficient method of triggering an action on a subcomponent in React Redux without the need to pass props down the component tree

Currently in the process of learning how to utilize react, redux, and react-redux with a straightforward requirement. I aim to display something similar to the layout below... -------------------------------- | title 1 |----------| | | descriptio ...

Multiple asynchronous calls in Angular 2

In my Component, there is a function that is supposed to return a value (Promise). This value requires information from two distinct sources: an API call and data from a database. The method in question looks like this: public getValue(): Promise<numb ...

Passing the array as query parameters and retrieving it using the angular getAll function is the most efficient way

When using this function, I extract the ids of items and aim to send them as an array for retrieval with getAll(). const queryParams: Record<string, string[]> = selectedItems.reduce( (acc, curr, index) => ({ ...acc, [&apo ...

Enhancing User Authentication: Vue 3 with TypeScript Login

Recently, I came across a new technology called Supabase and noticed that most resources mention registration on JavaScript instead of TypeScript. As I started working on a project using Vue 3 + TypeScript, I encountered some errors that I need help resolv ...

The parameter 'any' cannot be assigned to the parameter 'never' - Array provided is incompatible

Currently delving into TypeScript and encountering an issue while setting a reducer in redux Toolkit. Here's the code snippet in question: const testSlice = createSlice({ name: "test", initialState: [], reducers: { callApi: (state, ...

Personalized path-finding tree iterator

I am trying to implement a custom iterator in JavaScript that can traverse a DOM tree based on specific criteria provided by a callback function. The goal is to return an array of the nodes that match the criteria as the generator iterates through the tree ...

Tips on adding an external type to a global .d.ts file

In my TypeScript project, I am utilizing Moment.js for dealing with datetime objects. As part of this, I wish to create an object type that includes a key holding a value of type Moment. However, upon adding the following snippet to a global definition fi ...

Function not functioning as expected in NestJS MongoDB unique field feature

I am trying to set the "unique:true" attribute for the name property in my NestJS - MongoDB schema, but it is not working as expected by default. @Schema() export class User { @Prop() userId:string; @Prop({ type:String, required:true, } ...

Could someone provide a detailed explanation of exhaustMap in the context of Angular using rxjs?

import { HttpHandler, HttpInterceptor, HttpParams, HttpRequest, } from '@angular/common/http'; import { Injectable } from '@core/services/auth.service'; import { exhaustMap, take } from 'rxjs/operators'; import { Authe ...

Implementing Login using Google in a Nativescript iOS application: A step-by-step guide

I've been working on implementing Google's ID provider login in Nativescript using the nativescript-social-login plugin. While it works smoothly on Android, I've hit a roadblock with iOS. Following the instructions from the plugin creator, ...

Using Angular's ngFor directive to render 3 buttons in each row

I am attempting to show 3 buttons per div with the class "row". Using *ngFor to loop through the array to display buttons with the correct text. Here is a sample of my data: [{"NODE_ID":21.0,"NODE_DESC":"TERMINAL ASSEMBLY",&q ...

What is the method for utilizing OR statements in Playwright assert?

How can I verify whether the text content is either one or two using Playwright? await expect(this.header).toHaveText('one').or('two') Is there a way to achieve this functionality in Playwright? Additionally, can this feature be inco ...

How come my uploaded Excel Javascript add-on opens in an external browser instead of the task pane?

Note: It has come to my attention that I must save the taskpane.html file on my local drive before it opens in an external browser. This detail slipped my notice last week. I am currently developing a Javascript, or rather Typescript, API add-in for Excel ...

What is the best way to merge two interfaces and convert all of their fields to optional properties?

I have two unalterable interfaces: interface Person { name: string; age: number; } interface User { username: string; password: string; } I aim to merge them into a single interface called Player // please, adjust this code accordingly interfac ...

Angular 2 Demonstrate Concealing and Revealing an Element

I am currently facing an issue with toggling the visibility of an element based on a boolean variable in Angular 2. Below is the code snippet for showing and hiding the div: <div *ngIf="edited==true" class="alert alert-success alert-dismissible fade i ...

`How can I extract HTMLElements from slots in vue3?`

When attempting to develop a Layer component, I encountered some challenges. Here is the code: // Wrapper.vue <template> <slot v-bind="attrs"></slot> </template> <script lang="ts" setup> import { defi ...

Having trouble retrieving values from Promise.allSettled on Node.js 12 using TypeScript version 3.8.3

Currently, I am delving into NodeJs 12 and exploring the Promise.allSettled() function along with its application. The code snippet that I have crafted allows me to display the status in the console, but there seems to be a hitch when attempting to print t ...

Using selectors and mappers in Typescript generics

I am looking to create a versatile selector and mapper method. interface State { user: { name: string; age: number; } } const pickName = (state: State) => state.user.name; const selectAge = (state: State) => state.user.age; ...