'Typing rest operator object in TypeScript

I was trying to remove a property from an Object using the rest operator and could not figure out how to force a type on the new Object.

interface Ab {
  a: string;
  b: number;
}

interface Bc {
  b: number;
  c: boolean | undefined;
}

const ab: Ab = { a: 'a', b: 1};
const {a, ...bc} = {...ab, c: true};

I know that bc now has a type

{
  b: number;
  c: boolean;
}

is there a way to force bc to be explicitly of type Bc?



Solution 1:[1]

Actually it's pretty fun and tricky question :) So here is my solution:

interface Abc extends Ab, Bc {
  bc: Bc;
}

const ab: Ab = { a: 'a', b: 1};
const { a, ...bc }: Abc = { ...ab, c: true } as Abc;

Playground link

Solution 2:[2]

It feels like what you're trying to achieve is very particular to the case you're handling at the moment and not something that can be applied in general.

If I were to take your original example and rename some variables and types (without changing any code), I could get this:

interface Human {
  intelligenceQuotient: number;
  speed: number;
}

interface Dog {
  speed: number;
  name: boolean | undefined;
}

const david: Human = { intelligenceQuotient: 100, speed: 5};
const {intelligenceQuotient, ...bc} = {...david, name: "David"};

Your question then becomes:
If I remove the intelligenceQuotient from david and give him a name, then why doesn't he become a Dog?

A simplified version of the code in your question would be:

interface Human {
  numberOfLegs: number;
}

interface Dog {
  numberOfLegs: number;
}

interface DogWithName extends Dog {
  petName: string;
}

const dog: DogWithName = { numberOfLegs: 4, petName: "Snowy" };
const { petName, ...rest } = dog;

rest is neither Dog nor Human, it is of type { numberOfLegs: number; }.

Solution 3:[3]

Start of by using a destructuring assignement to extract the seg, min and variable properties from the dia object.

const { seg, min, variable } = dia;

Then create a new object in which you set the seg and min properties with the destructured properties. For the variable property, use the spread syntax to place the properties of variable inside the same object.

const result = {
  seg,
  min,
  ...variable
};

const dia = {
  seg: 60,
  min: 1,
  variable: {
    dias: 7,
    semana: 1
  }
};

const { seg, min, variable } = dia;

const result = {
  seg,
  min,
  ...variable
};

console.log(result);

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Stanislas
Solution 3 Emiel Zuurbier