I'm mapping an array of objects loaded from JSON into objects of a known type. I used the standard array.map, but I was able to specify additional properties without a compiler error. But if I explicitly specify the return value type in the map function, the compiler forbids the additional properties.
interface Foo {
name: string
}
const input: any[] = [{ name: 'Jen' }]
// Compiles. But 'extra' is not in Foo and Foo[] is the specified return type.
const mapped1: Foo[] = input.map((item) => ({
name: item.name,
extra: true
}))
// Does not compile. But this is excessively verbose.
const mapped2: Foo[] = input.map((item) => {
const output: Foo = {
name: item.name,
extra: true
}
return output
})
Can someone explain why the compiler isn't complaining about the first one but not the second? Is there another way to do this? Thank you!
TypeScript is a structurally typed language, meaning that extra properties are not considered type errors except for the very specific case of having a literal object. The reasoning for this can be found in the related issue.
There is another way to write this that is less verbose but will still get you what you want. The idea is to add an explicit return type for the mapping function so that literal object case triggers. In this case you also do not need annotation on the result:
const mapped3 = input.map((item): Foo => ({
name: item.name,
extra: true
}))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With