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 :P
How can I use the spread operator and still return the same type?
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
.
CodePudding user response:
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 correction, just T & { size: string }
T
should be fine because you already have size
in AnimalProps
.
CodePudding user response:
This can easily be addressed by using a generic constraint:
function addSizeUnits<A extends Animal>(animal: A): A {
return { ...animal, size: `${animal.size} meters` };
}
This ensures that your argument type and your return type are the same type of Animal
.