Open
Description
Bug Report
🔎 Search Terms
class, extends, constructor, return primitive
🕗 Version & Regression Information
- This is the behavior in every version I tried, and I reviewed the FAQ for entries about class constructors
⏯ Playground Link
Playground link with relevant code
💻 Code
new class extends class {
constructor() {
return 1;
}
} {
constructor() {
super();
console.log(typeof this);
}
}
🙁 Actual behavior
Logs "number"
🙂 Expected behavior
Logs "object"
Metadata
Metadata
Assignees
Labels
Type
Projects
Milestone
Relationships
Development
No branches or pull requests
Activity
MartinJohns commentedon Dec 3, 2022
This is working as intended. It's legit JavaScript. For TypeScript to change this behaviour would violate the language design goals.Related: #38519 / #27594 / #13819
Josh-Cena commentedon Dec 3, 2022
@MartinJohns The change can be trivially done in the downleveling—it requires no type information.
FWIW, anything that Babel does right but tsc does wrong looks like a bug to me.
MartinJohns commentedon Dec 3, 2022
Nevermind my earlier comment. I wrongly assumed the JavaScript will behave the same.
fatcerberus commentedon Dec 3, 2022
You probably should have specified that this only happens with ES5-downleveled code. From the OP it seemed like you meant this happened regardless of
target
(which would indicate it was just normal JS behavior).[-]Base class constructor's primitive return value should be ignored[/-][+]ES5 output: Base class constructor's primitive return value should be ignored[/+][-]ES5 output: Base class constructor's primitive return value should be ignored[/-][+]In target: ES5, Base class constructor's primitive return value should be ignored[/+]RyanCavanaugh commentedon Dec 5, 2022
You should use Babel in that case. The TS emit takes some complexity/compliance tradeoffs and is much less configurable.
I don't think we want to risk breaking any ES5 programs at this point given how old of a target it is.
Josh-Cena commentedon Dec 6, 2022
I can guess the historical context here (tsc implementing classes before the latter getting standardized), but IMO the current behavior doesn't benefit anyone and is unlikely to be relied on. If
this
is a primitive, it means you can't mutate it whatsoever. Unless you do something really weird like:But that doesn't even get correct types! Why would someone use tsc, choose its bizarre subclassing behavior, but also disregard the types?
Built-in subclassing not working is a missed but understandable tradeoff, but this one seems niche and not as breaking-change-prone, while increasing tsc's conformance.