TypeScript: Incorrect "'value' is specified more than once, so this usage will be overwritten. ts(2783)"

TypeScript Version: 3.9.2

Search Terms:

  • property-will-be-overwritten-by-spread
  • 2783
  • is specified more than once, so this usage will be overwritten
  • spread

Code

import { Select } from '@material-ui/core';

import React from 'react';

export function Repro({ SelectProps = {} }: { SelectProps?: Partial<React.ComponentProps<typeof Select>> }) {
    return (
        <Select value={'test'} {...SelectProps} />
    );
}

Expected behavior: No error, as value in SelectProps is optional and SelectProps even defaults to an empty object.

Actual behavior:

‘value’ is specified more than once, so this usage will be overwritten.ts(2783) Repro.tsx(7, 32): This spread always overwrites this property.

Playground Link: none, as the playground does not seem to load the material-ui types

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 23
  • Comments: 36 (4 by maintainers)

Commits related to this issue

Most upvoted comments

I noticed that this issue has 4.0 as milestone. If 4.0 will have breaking changes and this bug was introduced in 3.9.2, it might be worth to consider making a fix for this bug in 3.9.x?

@DanielRosenwasser 3.9.3 not work

FWIW, for people like me who find themselves on this thread, this problem is resolved in React by including the prop after a spread:

// Error: image

// No error: image

Same problem with 3.9.6

@yogeshkotadiya without knowing the type of payload, that message can be perfectly valid. Does the type of payload contain a non-optional addressNickName property? Then the message is correct and telling you that addressNickName: "Home" will always be overridden by payload.addressNickName so you can leave it out. In that case, it is not this bug.

I’m not sure what you want from me, but:

  • The original issue is fixed, and published in version 3.9.3, as indicated by the milestone and associated PR activity.
  • @AlexanderVishnevsky commented between us closing the issue and publishing 3.9.3, so didn’t have the patch (his comment includes a reference to 3.9.2)
  • @yamuun is just confused about the error message (which is in his case correctly issued, as @artem-malko explained) and likely posted here because the recent activity is making this issue rank higher than relevant stackoverflow posts (probably), and
  • I don’t know what @b2whats is in here for, since the original issue is definitely fixed. If he’s still having some kind of a problem, we’ll definitely need to know more than “3.9.3 not work”.

The issue is not resolved in 3.9.3

'addressNickName' is specified more than once, so this usage will be overwritten.
const data: Address = {
	addressNickName: "Home",
	streetName: "12th Street",
   	...payload,
};

Should be fixed now

Same problem with

   "@material-ui/core": "4.9.14",
   "typescript": "3.9.2",

Reverting typescript to "typescript": "3.8.3", solves the problem.

@nisimjoseph If the object you are receiving does not contains all the mandatory fields, then it is not a Config object. The easiest solution I see to do what you want is changing your code to

function send(config:Config) {
	const finalConfig:Config = {
		publisher: "name",
		Version: "1.0",
   		...config as {},
	}
}

Anyway, this is not a bug: compiler is right.

I am using TS 3.9.6 and the issue still exist. see the simple code here:

interface Config {
	Version:string;
	publisher:string;
}

function send(config:Config) {
	const finalConfig:Config = {
		publisher: "name",
		Version: "1.0",
		...config,
	}
}

Get error: TS2783: 'publisher' is specified more than once, so this usage will be overwritten. When I do ...<any>config, it pass, but I do want the static check which I can’t get now.

Which has a different runtime behaviour and exactly what the error is warning about. In the first case, assuming the types were correct, iconOnly would always be overwritten and never actually have that value. You probably don’t intend that, which is why you get the error.

@Talent-Rain

  • SelectProps is a Partial property. This means every of it properties can be there, but it could also be not. It will not necessarily be overridden, but it could be. Which is fine, and a case where that error message should not have shown up.
  • This was a bug report. It was accepted as a bug. It was fixed. 6 Months ago. It does not happen again. Everyone who posted here after that had another problem or did not correctly interpret the error message that was correctly shown to them for reasons unrelated to this bug.

Could we please stop posting unrelated stuff here? This issue has been fixed and everything after that is either worthy of a new ticket or not of interest any more, as this bug has been fixed.

@phryneas nvm. I leave it here for the log: when I was trying to create a simple snippet to replicate the issue, I noticed it was compiling fine. So the solution jumped to my mind. The error resides in the as AndroidVariant and as IOSVariant since they both inherit from Variant whose definition is:

export interface Variant {
  id: string;
  variantID: string;
  name: string;
  description: string;
  developer: string;
  secret: string;
  type: VariantType;
  metadata?: {
    activity: number;
    deviceCount: number;
  };
}

So, even if I don’t really specify the name two times, since it is defined as mandatory in the base interface the compiler sees it as specified 2 times: my error, compiler was right.

@yamuun it’s useless to write

const hoge = {
    age: 20,
    area: 'NY',
    title: 'Sales Manager',
    ...person,
};

cause age won’t be 20 in hoge. The spread always overwrites age property. So, it’s ok to see “This spread always overwrites this property”.