Skip to content
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

No error when attempting to read a write-only property #11596

Closed
battmanz opened this issue Oct 13, 2016 · 12 comments
Closed

No error when attempting to read a write-only property #11596

battmanz opened this issue Oct 13, 2016 · 12 comments
Labels
Duplicate An existing issue was already created

Comments

@battmanz
Copy link

battmanz commented Oct 13, 2016

TypeScript Version: 2.0.3

Code

// This works as expected
class Demo1 {
  get foo() {
    return 'hi';
  }
}

let d1 = new Demo1();
d1.foo = 'wat'; // An error is given (as it should be) because foo is read-only.

// This does NOT work as expected
class Demo2 {
  private _foo: string;

  set foo(foo: string) {
    this._foo = foo;
  }
}

let d2 = new Demo2();
console.log(d2.foo); // No error, but there should be because foo is write-only.

Expected behavior:
A compiler error should be given when attempting to read a write-only property.

Actual behavior:
There is no compiler error.

@battmanz battmanz changed the title No error when attempting to read a "set-only" property No error when attempting to read a write-only property Oct 13, 2016
@mhegazy mhegazy added the Working as Intended The behavior described is the intended behavior; this is not a bug label Oct 13, 2016
@mhegazy
Copy link
Contributor

mhegazy commented Oct 13, 2016

This is working as intended. a write only property is not very useful, and is not something that is supported in the type system. the two supported variations are readonly, and read-write.

@battmanz
Copy link
Author

battmanz commented Oct 13, 2016

I agree that write-only properties aren't used very often, but just to be consistent/complete, I would think that if the language supports readonly properties then it would support write-only properties as well. In C#, for example, I would get an error if I tried to read a property that only had a setter.

If the language truly does not support write-only properties, as you say, then please give a compile time error if I try to do so. So to update my earlier example:

class Demo2 {
  private _foo: string;

  set foo(foo: string) { // error: write-only properties are not allowed
    this._foo = foo;
  }
}

@mhegazy
Copy link
Contributor

mhegazy commented Oct 14, 2016

JS allows getter-only and setter-only properties. so at runtime this code would work. the write would invoke the setter, the read would always return undefined. The type system does not model it. there is read/write, and read-only but no write-only.

I see the proposal of making it an error. it just does not happen that often, but we can discuss it.

@mhegazy mhegazy added In Discussion Not yet reached consensus Suggestion An idea for TypeScript and removed Working as Intended The behavior described is the intended behavior; this is not a bug labels Oct 14, 2016
@aluanhaddad
Copy link
Contributor

I don't think it should be an error to define a property with only a set attribute. It might be nice if it was an error to use such a property in an rvalue context. I'm guessing that this would make assignability analysis much more complicated for little benefit.

@dungdm93
Copy link

dungdm93 commented Oct 27, 2016

I think TypeScript should cover more cases as:

interface Foo {
    foo: string;    // abstract property = getter + setter
}

// No compile error, but there should be because no foo's setter implemented.
class Bar implements Foo {
    private bar: string = "Batman";
    get foo(): string {
        return this.bar;
    }
}

// No compile error, but there should be because no foo's getter implemented.
class Baz implements Foo {
    private baz: string = "Superman";
    set foo(value: string) {
        this.baz = value;
    }
}

// No compile error, but there should be because Quiz.foo not match Foo.foo signature
class Quiz implements Foo {
    readonly foo: string = "Iron man";
}

// This is OK.
class Fine implements Foo {
    private fine: string = "Captain America";
    set foo(value: string) {
        this.fine = value;
    }
    get foo(): string {
        return this.fine;
    }
}

and even this

abstract class A {
     abstract get name(): string;
}

// No error at all. :((((((
class C extends A {
    foo: string;
    set name(value: string) {
        this.foo = name;
    }
}

@RyanCavanaugh RyanCavanaugh added Help Wanted You can do this and removed In Discussion Not yet reached consensus labels Oct 31, 2016
@RyanCavanaugh RyanCavanaugh added this to the Community milestone Oct 31, 2016
@RyanCavanaugh
Copy link
Member

We'd like to make a setter without a corresponding getter in the class be an error and see if this disrupts anyone too badly. PRs welcomed.

@DanielRosenwasser DanielRosenwasser added the Effort: Moderate Requires experience with the TypeScript codebase, but feasible. Harder than "Effort: Casual". label Nov 1, 2016
@Igorbek
Copy link
Contributor

Igorbek commented Nov 4, 2016

If use-site variance #10717 lands eventually, it will be useful to have write-only properties as a contravariant part of the property:

class C<T> {
  get foo(): T { ... }
  set foo(v: T) { ... }
}
interface A<T> { foo: T; }

C<out T> = { readonly foo: T; }
C<in T> = { writeonly foo: T; }
A<out T> = { readonly foo: T; }
A<in T> = { writeonly foo: T; }

@dead-claudia
Copy link

@RyanCavanaugh

Here's a use case for write-only properties: I developed a JS library which uses getters and setters extensively, and I have a couple write-only properties in it for changing settings that themselves don't make sense to "get".

  • One of the setters (accepts an array of selectors to limit tests run) transforms the assigned value to something much more optimized for internal use (a lookup tree).
  • One of the setters (accepts a Reporter | [Reporter] | [Reporter, {...opts}]) initializes the reporter with the options (if given), but only the result is stored.

I can't define them as write-only in TypeScript, despite them only having setters (no getters).

(The library idiomatically prefers properties over getter/setter methods for the API, to make it more intuitive.)

@larssn
Copy link

larssn commented Jul 31, 2018

Just wanted to chime in and say that writeonly properties can be useful for password-storing-fields.

@dead-claudia
Copy link

@larssn Not sure password storage is a good example of a write-only field. (DOM <input type="password"> fields have a readable value - you can't otherwise do interactive password-strength tests. It's also led to a few security breaches thanks to malicious trackers.)

ajafff added a commit to ajafff/TypeScript that referenced this issue Aug 9, 2018
@RyanCavanaugh RyanCavanaugh added Duplicate An existing issue was already created and removed Effort: Moderate Requires experience with the TypeScript codebase, but feasible. Harder than "Effort: Casual". Suggestion An idea for TypeScript Help Wanted You can do this labels Aug 23, 2018
@RyanCavanaugh RyanCavanaugh removed this from the Community milestone Aug 23, 2018
@RyanCavanaugh
Copy link
Member

The PR for this found that we'd end up breaking a reasonably large amount of code if we made set-only properties an error, so this proposal is effectively #21759 and we'll track it there

@typescript-bot
Copy link
Collaborator

This issue has been marked as a 'Duplicate' and has seen no recent activity. It has been automatically closed for house-keeping purposes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

10 participants