Skip to content

Spread syntax ignores generic type constraints #46146

@toolness

Description

@toolness

Bug Report

🔎 Search Terms

typescript extends spread

Through this I found #26412, which may be related to this, but I can't quite tell, in part because a code example that it claims raises a compile error in TS 3.0 no longer raises a compile error in 4.4.3. There appear to be a number of bugs related to that, but as far as I can tell, none of them match the particular problem I'm having. I might have missed one, though, in which case I apologize.

🕗 Version & Regression Information

4.4.3. Also happens in 4.5.0-dev.20210930 (see playground link below).

This is the behavior in every version I tried, and I reviewed the FAQ for entries containing the word extends and spread.

⏯ Playground Link

Here is a Playground link.

💻 Code

type Thing = {
  hello: number[];
}

function operateOnThingViaSpreadThenAssignment<T extends Thing>(thing: T): T {
  const newThing = { ...thing };
  // Here we are assigning a string instead of number[] to the "hello" property,
  // and TS raises a compile error as expected.
  newThing.hello = "hi";
  return newThing;
}

function operateOnThingViaSpreadOnly<T extends Thing>(thing: T): T {
  // Here we are assigning a string instead of number[] to the "hello" property,
  // but TS doesn't complain.
  return { ...thing, hello: "hi" };
}

🙁 Actual behavior

TypeScript appears to treat the two functions differently, correctly raising a compilation error for operateOnThingViaSpreadThenAssignment() while curiously being fine with operateOnThingViaSpreadOnly().

The latter seems particularly bad because, as far as I can tell, it's effectively not reporting something that is actually a type error.

🙂 Expected behavior

I expect TypeScript to raise the same error--or at least, something very similar, along the lines of Type 'string' is not assignable to type 'number[]'--for both functions.

Metadata

Metadata

Assignees

No one assigned

    Labels

    DuplicateAn existing issue was already created

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions