-
Notifications
You must be signed in to change notification settings - Fork 202
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
typings: module augmentation and side effects? #250
Comments
Ping @gf3 who seems to own the types here. |
Thanks @seansfkelley for the feedback! Changing how we extend moment would be a huge breaking change and right now can't find a better way. The solution If you can think of another way of extending moment without side affects please let us know! 😀 As for the typing issues you've identified - all except for the permissive |
To clarify -- I'm not proposing you change how you actually modify the moment instance at runtime, just how you declare the types. With the current types, you can only type-safely get at the import * as moment_ from "moment";
import { extendMoment } from "moment-range";
const moment = extendMoment(moment_); (This code may not compile exactly as-is -- I'm doing this from memory.) This gets tedious if you want to use However, this usage isn't 100% correct -- moment-range mutates the given moment, so in reality you can just My proposal/my forked typings/the way moment-timezone does it is also not 100% correct, but for what I assume is the common case is much more ergonomic. Either way is a bit of a lie:
I was advocating for switching to the more-ergonomic interface-merging declaration under the assumption that it's better to be slightly wrong in that direction than the current direction. |
As for the too-permissive
I can't think of any other way to resolve that issue. |
an additional consideration is after using the |
The typings as-is are more conservative at the cost of being less ergonomic, so if that's the tradeoff you want to make, I understand. In that case feel free to close this issue if you don't intend on making these changes; I don't see any other potential methods to achieve these improvements without sacrificing that conservativeness. |
@seansfkelley another option is to offer an export of moment pre-extended, which could then map to a merged declaration |
@seansfkelley thanks for your suggestions around the permissive
We can use
As we don't want to tie users to a specific version of moment, so I'd rather err on the side of permissive types than restrictive |
This could work. Are you imagining something along the lines of import * as moment from "moment-range/extended"; // or whatever it'll be called and then in I don't know off the top of my head how that would play with
But it might be worth pursuing.
This makes sense, though with module augmentation you don't need to redeclare the constructor (as I did in the original post). It's probably alright now though, since it doesn't clobber the constructor unless you ask it to with |
moment-range is rather difficult to type accurately.
extendMoment
is side-effecting and affects the (presumably global) copy of the library you pass it, but the typings mix module augmentation with more-localized changes:I've modified this part of the typings in my project such that it only performs module augmentation:
I would like to contribute these upstream, but there's a bit of a lie here in that the typings are stating that every copy of moment available anywhere always has the range functions. In practice, this is true, as there is generally only one copy and you'd figure out pretty fast if you forgot to call
extendMoment
. However, I understand if such a typing lie might not be desirable upstream.FWIW, moment-timezone, which similarly modifies and returns the moment library, also has the same lie which I've found works great in practice. There's a slight difference in that moment-timezone fetches its own copy of moment rather than having you
extendMoment
, but both libraries have the same misleading implication that the original moment library is untouched. As such, the typings have chosen to reflect the runtime reality by using augmentation for everything.There are also a smattering of other typing issues I identified in the process that I would also contribute:
resolvedrange
accepts a mix-and-match for the two arguments, but the current typings require that the types of the two matchrange
accepts nulls/undefinedMomentRange
is far, far too permissive (try calling nonsensical things likemoment(1, moment, new Date(), false, moment(), {}, "string", true)
in the tests)resolvedextendMoment
should only take atypeof moment
, not aMoment
The text was updated successfully, but these errors were encountered: