-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
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
Initial work to make plugins type-safe (typescript) #463
Conversation
Codecov Report
@@ Coverage Diff @@
## dev #463 +/- ##
===================================
Coverage 100% 100%
===================================
Files 58 58
Lines 511 511
Branches 85 85
===================================
Hits 511 511 Continue to review full report at Codecov.
|
There's an issue with the way the type is defined at the moment. I'm going to work on that and reopen it when it works. |
Thanks, I'll need some time learning some TS declaration file basic concept with the help of your PR, and reviewers welcome. |
5dc8ff4
to
2e4b42c
Compare
Not sure if this helps, but according to this doc something like |
To do what? Seems like it's for global variables, which |
That is a misunderstanding that I had then. Throw my comment in the "unhelpful" bucket in that case. |
I have an interesting finding. While using dayjs v1.8.5 in a typescript, and we want to use plugin
and in the project
|
@iamkun This was one of my issues with module augmentation, as stated here (option 5). |
Oh I see. I didn't know this is called module augmentation.
|
@iamkun Yea, this does work, but doesn't offer any type-safety as far as the actual /* Option #1 - re-export and get type safety through type inference */
// config/dayjs.ts
import dayjs from 'dayjs';
import relativeTime from 'dayjs/plugin/relativeTime';
export default dayjs.extend(relativeTime);
// some-other-file.ts
import dayjs from '../config/dayjs';
dayjs().toNow(); // no error since dayjs is inferred to be of type Dayjs<RelativeTimePlugin>
/* Option #2 - cast it yourself */
// config/dayjs.ts
import dayjs from 'dayjs';
import relativeTime from 'dayjs/plugin/relativeTime';
// just making the call here to mutate the prototype
dayjs.extend(relativeTime);
// some-other-file.ts
import dayjs from 'dayjs';
import relativeTime from 'dayjs/plugin/relativeTime';
dayjs().toNow(); // type error
(dayjs() as Dayjs<RelativeTimePlugin>).toNow() // no type error - though you are telling the compiler to trust you on the type here. Is there anything blocking this PR or that requires further discussion? |
- move inside /src for auto-detection by tsc - fix UnitType type to match actual js code - change signature of PluginFunc and extend to allow better type handling # Conflicts: # package.json
# Conflicts: # src/index.d.ts
# Conflicts: # src/index.d.ts
# Conflicts: # src/index.d.ts
# Conflicts: # src/index.d.ts
d9f4d35
to
2cde4d7
Compare
…r static plugins
I can't make this pr work on my side. I've copied the code to And in my ts project
|
@iamkun what do you mean by your side? I'd appreciate it if you could send a link to a repo with the current state you're in. I'll try to see if there's anything missing, on either end. |
@bengry check the invitation please |
@iamkun I looked at the code, and pushed to a new branch there ( |
@bengry Oh, thanks.
However, it looks a little bit wired to me and a bit complicated. I think We might not need that strict type checking, right? |
I agree that this is more convoluted then module augmentation, but it's the best thing I could think of but being type-safe. I think we may be able to get this working alongside module augmentation (so you can choose how to go about doing this), but this requires further exploration, and may require separating the dayjs plugins into separate packages (one per plugin), to allow it to be really seamless, which would be a breaking change - something I wanted to avoid so far. What do you think? |
Yes, I know it's better than module augmentation of being type safe. And we really can't check whether But, to me, I think Day.js is just a tiny simple date-time utils library, you could see this from its size. And I really don't want our user to create a separate file to make everything work on their project for this small library. That is to say, it shoud be a out of the box solution. That's what a lib should really do. How do you think? |
While I do see this as a library that could be used in large apps, I get what you're saying. I'm not sure when exactly I'll have time for this, but I'll try to get to it soon. Would having both approaches (with appropriate docs in the day.js docs) be satisfactory? |
Will it takes you a lot of time? If so, we could use We could finish the full version in two or more PRs, and no need to do everything here. |
I'm not sure, since I'd like to get both working with one codebase. You can use the definitions I created for some of the plugins here for the module augmentation. |
Agreed, cool. So, step one, we could start from module augmentation, and make basic plugin type check work. And step two, make If I understand this correctly, I could start step one this weekend with the help of your code in this PR, this comment #463 (comment), and #418. Or you could create a new PR if you want your code get merged. Both are fine to me. |
@iamkun #418 looks good overall (there are some unrelated changes there, and the |
ConfigType change was intended. Actual config is appear here: Line 37 in f343206
It is object passed to Dayjs constructor, which contains date, format and locale. Though it is already reverted in below commit 😂 |
@ypresto We could do the rename later 😂 |
I'm +1 for keeping module augmentation only, because place-by-place installation of plugins for strict type-safety is too much for most of users. |
@ypresto I do agree with you at this moment. But we could still wait for feedback after our first module augmentation version release. |
@bengry Just released v1.8.7 with module augmentation. We could wait for feedback and decide what to do next. |
looks we are fine now and can close this PR. Thank you anyway. |
All changes are in types only, and and thus not breaking changes as far as runtime is concerned.
The changes are essentially an implementation of option 3 from my comment in #364.
Do note that it will break plugins that reference
PluginFunc
, since it now requires a generic (this can be avoided with default generics, but there's a good point not to give defaults in this case. I can expand on this if needed).I also made a small change to the type of
UnitType
to allow more units to be passed in, seeing that the source allows it. I can pull that into a separate PR if needed.Lastly, I moved the
index.d.ts
file into the/src
folder, for easier automatic detection by tsc inside the repo. This is unsolved (together with the definition file for therelativeTime
plugin I made as an example. Both of these files should be copied over and included in the final bundle.Update: adding types for so-called "static plugins" is now possible (like the
customParseFormat
plugin, which modifies the dayjs namespace, and not the prototype). There is a little overhead for plugin type authors, but it's very minimal. See the type forcustomParseFormat
plugin as an example.