Skip to content

Shorthand restricting accessor accessibility. (get; private set; inspired by C#) #48362

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
twoco opened this issue Mar 21, 2022 · 7 comments
Closed
Labels
Out of Scope This idea sits outside of the TypeScript language design constraints Suggestion An idea for TypeScript

Comments

@twoco
Copy link

twoco commented Mar 21, 2022

Suggestion

🔍 Search Terms

  • private set
  • shorthand accessor

⭐ Suggestion

In C# you can do this:

public class User {
  public string Name { get; private set; } 
}

to reach this in TypeScript you have to write a short novel:

export class User {
  private _name: string;
  public get name(): string {
    return this._name;
  }
  private set name(name: string) {
    this._name = name;
  }
}

This works great. But is a lot of code for such a tiny thing.

Write less code with less risk of errors. Otherwise you have to create a mirrored variable with e.g. leading _ underscore. And write this stupid short code. It's harder to read. You write the name and types over and over again. And possible make a mistake. But anyway, it would great to short up this by C# inspired syntax or a new keyword. Something between private and public. A keyword for private set; public get.

But I'm not sure how TypeScript will handle this. I think code needs to be added to JavaScript during compilation. But how to avoid collisions? I mean just adding _{variableName} is maybe not the best idea. It must be added to a hidden layer. ... Anyway, this is just a suggestion hoping you have a better idea than me.

The syntax can be similar to C# or a new keyword. It world be create to have a short way to make a property readonly for public and writeable in private scope. In best case with an initial value.

class User {
  public get private set name = 'Foo';
}
@whzx5byb
Copy link

Duplicate of #37487

@MartinJohns
Copy link
Contributor

MartinJohns commented Mar 21, 2022

You forgot to fill out the issue template for feature requests. It contains a "viability checklist" which pretty much rules your suggestion out.

  • This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)

@RyanCavanaugh RyanCavanaugh added Suggestion An idea for TypeScript Out of Scope This idea sits outside of the TypeScript language design constraints labels Mar 21, 2022
@RyanCavanaugh
Copy link
Member

C# recommends everyone use property getters/setters because you incur a binary API break when changing a field to an accessor pair, but this is a much much smaller problem in JavaScript -- wrapping a bare field with a get/set pair is not something you should be doing regularly, so there's no syntax in JS or TS for this.

@fatcerberus
Copy link

wrapping a bare field with a get/set pair is not something you should be doing regularly, so there's no syntax in JS or TS for this.

@RyanCavanaugh The main motivation here seems to be less about the property shorthand and more "I want to have a property that can only be written from inside the class"

@RyanCavanaugh
Copy link
Member

True; I guess my comment applies more to the non-#37487 aspects of this

@twoco
Copy link
Author

twoco commented Mar 21, 2022

Yes, it's about public readonly but internally it's still writable. Initally I thought the keyword readonly is the right one. But it's more like final (in Java or Dart). To be honest, the TypeScript readonly should be rather final and readonly for our public case here. By docs:

Java (wiki, cuz oracle docs s*cks. I'm not a Java dev.) - final - In Java, the final keyword is used in several contexts to define an entity that can only be assigned once.

Dart - final - If you never intend to change a variable, use final or const, either instead of var or in addition to a type. A final variable can be set only once; a const variable is a compile-time constant. (Const variables are implicitly final.)

TypeScript - readonly - Fields may be prefixed with the readonly modifier. This prevents assignments to the field outside of the constructor.

Sounds very similar. Why doesn't TypeScript use the final keyword? Because of ES3? Since ES5 it's not reserved anymore. But does it matter? It only exists in TypeScript. So I would have readonly for public readonly and final for the current readonly behavior in TS. But anyway...

@MartinJohns
Copy link
Contributor

readonly does not prevent modifications. It just means "no write access via this interface". A type with readonly properties is implicitly compatible with the same type without the readonly modifier for it's fields.

When reading keywords I would assume final to mean immutable, something readonly explicitly is not.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Out of Scope This idea sits outside of the TypeScript language design constraints Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

5 participants