Open lordazzi opened 3 years ago
Please feel free to do it.
Is any news about it?
Yes, I'm waiting for my in home vacation into July. Then I will test some interfaces that I already written and publish this.
I'd also love to have these. Any news ?
@lordazzi @mymth Hello, any update on this ? Anyone that could direct me to achieve this for this lib, it has become a blocker for me when upgrading my project from angular 11 to angular 13.
Hello! This thread might be outdated but I tried npm i --save-dev @types/vanillajs-datepicker
and I can now import the library properly in Typescript.
Thanks @rougin, but how do you deal with locale ?
Thanks @rougin, but how do you deal with locale ?
Hi, I'm really not sure on how to answer this one as I did not use a specified locale for this package. However, as I checked from their documentation, the package supports i18n
: https://mymth.github.io/vanillajs-datepicker/#/i18n
Thanks for your reactivity ! I followed the documentation but typescript is not aware of the locales directories :/
@mmouterde You'll probably need a slightly longer path:
// Might need to append .js at the end, depending on config
import fr from 'vanillajs-datepicker/js/i18n/locales/fr';
//import fr from 'vanillajs-datepicker/js/i18n/locales/fr.js';
The shorter one only works if you use a bundler that supports package.json "exports" field
(from the i18n page).
But even if you fix the path, there are still problems actually using other languages. There are no types (yet) for the objects exported by those modules, so currently it simply exports a plain untyped object:
export default {
'en-GB': {
days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
daysShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
daysMin: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"],
months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
monthsShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
today: "Today",
monthsTitle: "Months",
clear: "Clear",
weekStart: 1,
format: "dd/mm/yyyy"
}
};
And TypeScript refuses to load it if you have noImplicitAny
set to true
in your tsconfig.json
:
Could not find a declaration file for module 'vanillajs-datepicker/js/i18n/locales/en-GB'. '/some/project/directory/node_modules/vanillajs-datepicker/js/i18n/locales/en-GB.js' implicitly has an 'any' type.
Even if you disabled that rule, you still don't know what properties the objects hold. I did figure out a project-level workaround though. Of course the best fix would be to actually add types to the DefinitelyTyped
repo, but I'll leave that to the developer.
Anyway, what I did was create 2 files (in a location already known to the bundler):
vanillajs-datepicker-locale.d.ts
type VanillaJsLocale = {
/** Text for the clear button */
clear?: string;
/** The full names of the days, starting at Sunday */
days: string[];
/** Short representations of the days' names, starting at Sunday */
daysShort: string[];
/** Shortest possible representations of the days' names, starting at Sunday */
daysMin: string[];
/** Date format string */
format?: string;
/** The full names of the months, starting at January obviously */
months: string[];
/** Short representations of the months' names, starting at January obviously */
monthsShort: string[];
/** Doesn't seem to be used? */
monthsTitle?: string;
/** Right to left */
rtl?: boolean;
/** Date format string for the picker's main title */
titleFormat?: string;
/** Text for the "today" button */
today: string;
/** First day of the week, with 0 being Sunday and 6 is Saturday */
weekStart?: number;
};
type VanillaJsLocaleLoaded = VanillaJsLocale & {
// These are copied from the default locale if they're not assigned "manually"
format: string;
weekStart: number;
};
type VanillaJsLocaleList<locale extends string = string> = {
};
declare module 'vanillajs-datepicker/locales/nl' {
const VanillaJsLocale_nl: VanillaJsLocaleList<'nl'>;
export default VanillaJsLocale_nl;
}
declare module 'vanillajs-datepicker/locales/en-GB' {
const VanillaJsLocale_en_GB: VanillaJsLocaleList<'en-GB'>;
export default VanillaJsLocale_en_GB;
}
I determined the optional keys by grepping through the JavaScript and checking what is missing in at least one locale.
vanillajs-datepicker.ts
(yes, .ts
and not .d.ts
because this is actually a module)
// We can't use `declare module` for this because it's not supported to merge existing declarations in the way we need ;_;
import DatepickerLib, { type DatepickerOptions as DatepickerOptionsLib } from 'vanillajs-datepicker/Datepicker';
import DateRangePickerLib from 'vanillajs-datepicker/DateRangePicker';
export interface DatepickerOptionsFormat {
toValue: (date: string, format: object, locale: VanillaJsLocaleLoaded) => number|undefined;
toDisplay: (date: Date, format: object, locale: VanillaJsLocaleLoaded) => string;
}
// @ts-expect-error We "incorrectly" extend a class but in this case there's no other way lel
export interface DatepickerOptions extends DatepickerOptionsLib {
format?: string | DatepickerOptionsFormat;
}
export interface DateRangePickerOptions extends DatepickerOptions {
allowOneSidedRange?: boolean;
inputs?: HTMLElement[];
}
export default class Datepicker extends DatepickerLib {
public constructor(element: HTMLElement, options?: DatepickerOptions, rangepicker?: DateRangePicker) {
// @ts-expect-error No other way lel
super(element, options, rangepicker);
}
public static override get locales(): VanillaJsLocaleList {
return DatepickerLib.locales as VanillaJsLocaleList;
}
}
export class DateRangePicker extends DateRangePickerLib {
public constructor(element: HTMLElement, options?: DateRangePickerOptions) {
// @ts-expect-error No other way lel
super(element, options);
}
}
And finally, in your project you can then do:
import Datepicker from './path/to/your/vanillajs-datepicker';
//import { DateRangePicker } from './path/to/your/vanillajs-datepicker';
import nl from 'vanillajs-datepicker/locales/nl';
import enGb from 'vanillajs-datepicker/locales/en-GB';
Object.assign(Datepicker.locales, nl, enGb);
console.log(Datepicker.locales); // Ok
console.log(Datepicker.locales.nl?.days); // Ok
console.log(nl.days); // Error, property 'days' doesn't exist
console.log(nl.nl.days); // Because you need to do it like this, due to the way the locale exports are structured
console.log(nl['nl'].days); // Ok too of course
console.log(nl['en-GB'].days); // Error, property 'en-GB' doesn't exist
console.log(enGb['en-GB'].days); // Ok
Hello, good afternoon. I'm using your lib as a part of a project in angular, but typescript compatibility is necessary, so I wrote the typescript definitions files and now it is just ready to be published in microsoft @DefinitelyTyped repository.
If I got your bless, I will create a pull request to microsoft create the @types/vanillajs-datepicker package.