This is usually where I digress into a long lecture about the difference between types and values in TypeScript, but here I'll try to make it short: since MyObject
is only known to be a type and not a constructor value, you can't call new MyObject()
. Instead, if you want to make a value of type MyObject
, you can just use a plain old object of the right shape, such as via object literal notation:
const myObject: MyObject = {name: "Alice"}; // no error
So your map
function can be the following:
const array2: MyObject[] = array1.map(s => ({name: s})); // no error
Simple, right?
Uh, well, please note as in the comments above that the parentheses around {name: s}
are necessary, because for better or worse, JavaScript parsers interpret arrow functions of the form (x => {...})
as having a block body where the stuff inside the curly braces are statements. And when you interpret name: s
as a statement it means that name
is a label, and s
is just a string expression statement with the optional semicolon omitted. Interpreted as a function body, {name: s}
just evaluates s
and doesn't return a defined value (it is void
, which is essentially the same as undefined
), which is why you get the following weird error if you leave out the parentheses:
let array2: MyObject[] = array1.map(s => { name: s }); // error!
// Type 'void[]' is not assignable to type 'MyObject[]'.
// at runtime, array2 will be [undefined, undefined] which is not what you wanted
JavaScript parsing is a bit tricky this way. Adding the parentheses to make s => (...)
fixes it. Now the stuff after the arrow can only be interpreted as a concise body... that is, a single expression. And interpreting ({name: s})
as an expression yields the object literal that we wanted.
Yay, I avoided writing a book about types and values and somehow ended up writing a different book about expressions and statements. Oh well.