4 ms·
Can someone enlighten me on why they're doing two declarations, one empty returning `this` and the other, implemented, returning `any`? public connectorsEn
by slig 10y ago
Can someone enlighten me on why they're doing two declarations, one empty returning `this` and the other, implemented, returning `any`?
public connectorsEnabled(enabled: boolean): this;
public connectorsEnabled(enabled?: boolean): any {
if (enabled == null) {
return this._connectorsEnabled;
}
this._connectorsEnabled = enabled;
return this;
}
https://github.com/palantir/plottable/blob/develop/src/plots/waterfallPlot.ts#L31 https://github.com/palantir/plottable/blob/develop/src/plots...
- uitgewis 10y agoPossibly method overloading in the type signature. If `enabled` is supplied the return is `this`, otherwise `any`.
- talldan 10y agoMy guess is that if you call it with a boolean argument, it returns `this` for chaining purposes. Otherwise it returns the current value of `_connectorsEnabled`. There are two declarations for the different usages, and then the actual implementation can return `any`. It is a bit strange. edit - see also line 24, for the declaration of the usage without an argument: https://github.com/palantir/plottable/blob/develop/src/plots/waterfallPlot.ts#L24 https://github.com/palantir/plottable/blob/develop/src/plots...
- chrismorgan 10y agox.connectorsEnabled() on line 24 is a getter, returning the boolean. x.connectorsEnabled(boolean) on line 31 is a setter, return `this` for the benefit of method chaining. That then leaves the actual definition which goes through to the JavaScript: it has an optional argument to satisfy both plausible signatures and starts on line 32. In short, the first two are basically hints for TypeScript (if the signature is such-and-such, its return type is actually more restricted than `any`), while the third has the actual implementation. For something similar consider how the type of callback in `addEventListener(type, callback)` depends on `type`: it’s always going to be a function taking an Event, but for e.g. type 'mousedown' it’s actually more than that, it’s a MouseEvent. So the TypeScript definitions in dom.d.ts or whatever it is (I haven’t had opportunity to actively use TypeScript for a while) has a whole lot of definitions: `addEventListener('mousedown', (event: MouseEvent) => void)`, `addEventListener('focus', (event: FocusEvent) => void)`, &c. (And because it’s just definitions, not the implementation, there is no actual implementation of `addEventListener(string, (event: Event) => void)`. This connectorsEnabled case does have the actual implementation.) In type system terms, think of it as a very restricted form of dependent typing.
- talldan 10y agoIt feels complicated due to not using separate getter and setter functions. By splitting it into two functions the annotations could be reduced as well. I wonder what the reason for not taking that approach was.
- chrismorgan 10y agoIt’s common in JavaScript to have method overloading for getters and setters like this. jQuery is probably the best-known example; .css('property') is a getter and .css('property', value) a setter.
- saguiar 10y agoThe odd thing is that they are not using three: public connectorsEnabled(enabled: boolean): this; public connectorsEnabled(): boolean; public connectorsEnabled(enabled?: boolean): any { if (enabled == null) { return this._connectorsEnabled; } this._connectorsEnabled = enabled; return this; } In that way, typescript will use the most specific overload to do type checking, so you'll get an actual boolean when doing connectorsEnabled(); instead of any.
- chrismorgan 10y agoThere are all three. Just look up a bit.
- saguiar 10y agoThanks, it does make more sense now.