You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Allow type-level extraction of a class name as a string literal #43325
Because class names cannot be modified and are known at compile time, they should be more narrowly typed.
🔎 Search Terms
class
name
constructor
string
literal
typeof
infer
narrow
🕗 Version & Regression Information
This behavior exists on Nightly (i.e. 4.3.0-dev.20210316) and the current version (4.2.3). It exists as far back as the compiler does - I was thereby not sure whether to classify this as a "bug" or a "feature request".
classFoobar{}// @ts-ignore-error This emits an error as class names are readonly (as expected)Foobar.name="I can't name names"// FooName is of type string rather than expected "Foobar"typeFooName=(typeofFoobar)["name"]
🙁 Actual behavior
FooName is of type string
🙂 Expected behavior
I would expect FooName to be inferred as type "Foobar", since the name cannot change (as per its readonly status).
A simple use-case would be a string-to-constructor record, but my use-case is actually generating sort of custom compiler error messages using string template literals. Right now I'm using the workaround of having a name attribute on each class, but it would be nice to not require that for my end-users.
I doubt they will think this is a bug; the name property of a function/class constructor is indeed of type string. You might want to consider filling out the feature request template instead of the bug report template.
Oh, that would be a much stronger feature, assuming nameof in a type context would return a literal string type. I do think though that generally that types associated with class names should be inferred narrowly, for the same reason that:
constfoo="foobar";foo// Type is "foobar" because `foo` was defined to be const.
#4628 and #3841 highlight some of the issues surrounding the static side of classes. With the notable exception of the construct signature itself, the static side of a class is inherited by subclasses, and thus forms a type hierachy:
If the name property of a class constructor (or function) were to be strongly typed in the way you're asking for, then subclass constructors would never be assignable to superclass constructors (so let fooCtor: typeof Foo = Bar would be an error) and this would undoubtedly break quite a bit of real world code (this is one reason why I'm suggesting that you fill out the feature request template, as it asks you to consider such things).
At least the nameof feature wouldn't necessarily require subclass constructor compatibility to break.
Activity
jcalz commentedon Mar 21, 2021
I doubt they will think this is a bug; the
nameproperty of a function/class constructor is indeed of typestring. You might want to consider filling out the feature request template instead of the bug report template.Is this a dupe of #1579 maybe?
poteat commentedon Mar 21, 2021
Oh, that would be a much stronger feature, assuming
nameofin a type context would return a literal string type. I do think though that generally that types associated with class names should be inferred narrowly, for the same reason that:jcalz commentedon Mar 21, 2021
#4628 and #3841 highlight some of the issues surrounding the static side of classes. With the notable exception of the construct signature itself, the static side of a class is inherited by subclasses, and thus forms a type hierachy:
If the
nameproperty of a class constructor (or function) were to be strongly typed in the way you're asking for, then subclass constructors would never be assignable to superclass constructors (solet fooCtor: typeof Foo = Barwould be an error) and this would undoubtedly break quite a bit of real world code (this is one reason why I'm suggesting that you fill out the feature request template, as it asks you to consider such things).At least the
nameoffeature wouldn't necessarily require subclass constructor compatibility to break.poteat commentedon Mar 21, 2021
Thanks Joe Calzaretta (@jcalz) - I did not consider that.
I'm closing this out in lieu of #1579, as the current proposal above is unworkable (breaking changes is not my vision)