The initial line will throw an error because attempting to assign a boxed type to a primitive type, which is more specific.
The following line will not generate an error since converting a primitive type to a boxed type, which is less specific.
Returning to the first line:
let str = new String("bar");
console.log(typeof str); // object
The error message is really accurate:
'string' is classified as a primitive, while 'String' is considered a wrapper object.
You can still make it work by using type assertion: TypeScript complies, and then JavaScript unboxes the variable. Nevertheless, I struggle to comprehend why one may want to do such a thing:
let strVar: string = new String("bar") as string; // OK
Interestingly, you are also able to perform conversions with a slightly similar syntax:
let stringValue: string = String("baz"); // OK
console.log(typeof stringValue); // string
This approach proves to be particularly handy for Boolean conversions, like in this example:
const itemAvailable = Boolean(itemInStock);
console.log(typeof itemAvailable); // boolean