Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Return an instance of union type after spreading it

I have a general interface which I use to define properties (let’s say it’s an Animal).
Then I have extensions of this interface, which have additional different fields.

I want to define a function that gets an instance of an animal, spreads it – and parses a specific field.
The result value should be the same as the input’s; however I get an error, as not all animals are equal 😛

How can I use the spread operator and still return the same type?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

interface AnimalProps { name: string; size: string; }

class Dog implements AnimalProps {
  name: string;
  size: string;
  bark(): void { console.log(`${this.name} says: 'woof'`); }
  constructor(name: string, size: string) {
    this.name = name;
    this.size = size;
  }
}

class Bird implements AnimalProps {
  name: string;
  size: string;
  fly(): void  { console.log(`${this.name} says: 'I love flying'`); }
  constructor(name: string, size: string) {
    this.name = name;
    this.size = size;
  }
}

type Animal = Dog | Bird;
function addSizeUnits(animal: Animal): Animal {
  // Property 'fly' is missing in type '{ size: string; name: string; }' but required in type 'Bird'.
  return { ...animal, size: `${animal.size} meters` };
}

Obviously I’m simplifying the existing (legacy) code here, but the bottom line is that I do need to use fly and bark and therefore I need the actual union types – and not the basic Animal.

>Solution :

A generic function should work here. Something like:

function addSizeUnits<T extends Animal>(animal: T) {
  return { ...animal, size: `${animal.size} meters` };
}

Note that I removed the return type annotation because the type inference should figure that out for you, but if you want to add it back you can use something like T & { size: string } correction, just T should be fine because you already have size in AnimalProps.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading