-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Interface property not enforcing requirement for both getter and setter when implemented on a class #45517
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
Comments
The type system consistently treats properties only in terms of their "read" side; writes are always possibly-unsound due to e.g. the absence of a setter, or because the property type of the object is more specific than the property type specified by a reference to the object. |
Looks like a duplicate of #36575 and/or #13347. It has always been the case that you can assign a |
@RyanCavanaugh Do you think that the current behavior of setter-only accessors is as intended? class Foo {
set prop(x: string) { }
// no definite assignment error for prop
}
const f = new Foo();
f.prop.toUpperCase(); // no error when reading f.prop
// runtime error, f.prop is undefined If so I guess I'll leave this alone. If not maybe I'll open a separate issue. |
@RyanCavanaugh Thanks for the response. Does "Working as Intended" also mean "Working Correctly" in this case? Does that mean this will never be improved because of some fundamental type theory principle that TypeScript implements? Certainly the above scenario is in some way detectable. And I can't see why a developer wouldn't want to be informed at compile time of the runtime error and type inconsistency that occurs. const setterOnly = new MyClassWithSetterOnly() as IMyInterface;
const getterOnly = new MyClassWithGetterOnly() as IMyInterface;
console.log(setterOnly.property1); // Property returns `undefined` which is incompatible with `string`!
console.log(getterOnly.property1);
setterOnly.property1 = 'value';
getterOnly.property1 = 'value'; // Runtime [ERR]: Cannot set property property1 of # which has only a getter @jcalz Thanks! I also just found #21759 regarding the suggestion of a |
Other related but closed
However I'm not sure if the existence of |
Dropping a reference to ESLint's accessor-pairs linter rule here for anyone who wants to catch setter-only properties. |
Without a concept of Possibly with variant getters/setters we could consider synthesizing a Fundamentally there's no type system difference between class A implements HasM {
set m(v) { }
} and class A implements HasM {
get m() { throw new Error("ugh"); }
set m(v) { }
} so it's difficult to detect these via the normal assignability relationship. We'd need a separate additional pass on classes to validate that implemented properties didn't only have setters, but this costs cycles and is a fairly difficult mistake to make as a programmer. |
@RyanCavanaugh Thanks for the explanation! That makes sense to me. I think it's easier than you say to make the mistake. I have a case where I have an interface that some UI component implements. The setters update something visually in the component. Implementors of the interface may only opt to create setters since that's the minimum needed to get everything to work/compile. Later on, a user of the interface may opt to actually get one of those properties, and eventually find out later on at runtime that a particular implementation of the interface did not implement the getter. Implementations of this interface may exist in separate repositories adding to the complexity of getting the implementor to fix the issue. It would obviously be way more preferred if this was caught by the type checker. |
This issue has been marked 'Working as Intended' and has seen no recent activity. It has been automatically closed for house-keeping purposes. |
Bug Report
A property specified in an interface is not enforcing the requirement that both a getter and setter should exist when the interface is implemented on a class. See code example below...
🔎 Search Terms
interface getter setter accessor mutator property
🕗 Version & Regression Information
Seems to be an issue all the way from the nightly build back to 3.3.3 (as far as I can go back in the playground)
⏯ Playground Link
Playground link with relevant code
💻 Code
🙁 Actual behavior
implements
clause on Callout A's line above does not produce an errorimplements
clause on Callout B's line above does not produce an error🙂 Expected behavior
implements
clause on Callout A's line should produce an error similar to:implements
clause on Callout A's line should produce an error similar to:Understanding that missing half of a getter/setter set might produce a slightly different error for easier debugging and fix automation.
Alternative expectation
An alternative expectation may be for TypeScript to not allow a setter/getter to exist alone in any context (class, interface, object literal, etc). However, I imagine this would be very troubling for developers.
The text was updated successfully, but these errors were encountered: