Skip to content

Commit

Permalink
feat: Improve utils.date typescript typings (#658)
Browse files Browse the repository at this point in the history
closes #651
  • Loading branch information
dmtrKovalenko committed Jan 10, 2024
1 parent 1ce960e commit 50487b8
Show file tree
Hide file tree
Showing 13 changed files with 160 additions and 76 deletions.
12 changes: 3 additions & 9 deletions __tests__/hijri.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,7 @@ describe("Hijri", () => {
it("Hijri -- getYear", () => {
const date = hijriiUtils.date(TEST_TIMESTAMP);

expect(hijriiUtils.getYear(date)).toEqual(
1440
);
expect(hijriiUtils.getYear(date)).toEqual(1440);
});

it("Hijri -- setYear", () => {
Expand All @@ -65,9 +63,7 @@ describe("Hijri", () => {
it("Hijri -- getDate", () => {
const date = hijriiUtils.date(TEST_TIMESTAMP);

expect(hijriiUtils.getDate(date)).toEqual(
21
);
expect(hijriiUtils.getDate(date)).toEqual(21);
});

it("Hijri -- setDate", () => {
Expand All @@ -81,9 +77,7 @@ describe("Hijri", () => {
it("Hijri -- endOfYear", () => {
const date = hijriiUtils.date(TEST_TIMESTAMP);

expect(hijriiUtils.endOfYear(date).toISOString()).toEqual(
"2019-08-30T23:59:59.999Z"
);
expect(hijriiUtils.endOfYear(date).toISOString()).toEqual("2019-08-30T23:59:59.999Z");
});

it("Hijri -- startOfYear", () => {
Expand Down
2 changes: 1 addition & 1 deletion __tests__/inheritance.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { IUtils } from "@date-io/core/IUtils";
import DayjsUtils from "../packages/dayjs/src/dayjs-utils";
import { Dayjs } from "dayjs";

class CustomDateTime extends DayjsUtils implements IUtils<Dayjs> {
class CustomDateTime extends DayjsUtils implements IUtils<Dayjs, string> {
getYear = () => 2007;
getWeekdays = () => {
const start = this.dayjs().startOf("week");
Expand Down
4 changes: 2 additions & 2 deletions __tests__/test-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export const allUtils = [

export const utilsTest = (
name: string,
innerFn: (date: any, utils: IUtils<any>, currentLib: TestLib) => void
innerFn: (date: any, utils: IUtils<any, any>, currentLib: TestLib) => void
) => {
test.each(allUtils)(`%s -- ${name}`, (name, utils) =>
innerFn(utils.date(TEST_TIMESTAMP), utils, name)
Expand All @@ -33,7 +33,7 @@ export const localDateAllUtils = [

export const localDateutilsTest = (
name: string,
innerFn: (date: any, utils: IUtils<any>, currentLib: TestLib) => void
innerFn: (date: any, utils: IUtils<any, any>, currentLib: TestLib) => void
) => {
test.each(localDateAllUtils)(`%s -- ${name}`, (name, utils) =>
innerFn(utils.date(LOCALDATE_TEST_TIMESTAMP), utils, name)
Expand Down
35 changes: 30 additions & 5 deletions packages/core/IUtils.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,19 +66,44 @@ export type Unit =
| "seconds"
| "milliseconds";

export interface ExtendableDateType {}
type ConstructorOptions<TLocale> = {
formats?: Partial<DateIOFormats>;
locale?: TLocale;
instance?: any;
};

export interface IUtils<TDate extends ExtendableDateType> {
export interface IUtils<TDate, TLocale> {
formats: DateIOFormats<any>;
locale?: any;
locale?: TLocale;
moment?: any;
dayjs?: any;
/** Name of the library that is used right now */
lib: string;

// constructor (options?: { formats?: DateIOFormats, locale?: any, instance?: any });
// Constructor type
// new (options?: {
// formats?: Partial<DateIOFormats>;
// locale?: TLocale;
// instance?: any;
// }): IUtils<TDate, TLocale>;

date(value?: any): TDate | null;
/**
* Creates a date object. Use `utils.date()` to create a new date object of the underlying library.`
* Supports some of the standard input sources like ISO strings so you can pass the string directly
* as `utils.date("2024-01-10T14:30:00Z"), and javascript `Date` objects `utils.date(new Date())`.
*
* if `null` is passed `null` will be returned.
*/
date<
TArg extends unknown = undefined,
TResultingDate extends unknown = TArg extends null
? null
: TArg extends undefined
? TDate
: TDate | null
>(
value?: TArg
): TResultingDate;
toJsDate(value: TDate): Date;
parseISO(isString: string): TDate;
toISO(value: TDate): string;
Expand Down
19 changes: 13 additions & 6 deletions packages/date-fns-jalali/src/date-fns-jalali-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ var symbolMap = {
0: "۰",
};

export default class DateFnsJalaliUtils implements IUtils<Date> {
export default class DateFnsJalaliUtils implements IUtils<Date, Locale> {
public lib = "date-fns-jalali";
public locale?: Locale;
public formats: DateIOFormats;
Expand Down Expand Up @@ -300,17 +300,24 @@ export default class DateFnsJalaliUtils implements IUtils<Date> {
return setDate(value, count);
};

public date = (value?: string | number | Date) => {
date<
TArg extends unknown = undefined,
TRes extends unknown = TArg extends null
? null
: TArg extends undefined
? Date
: Date | null
>(value?: TArg): TRes {
if (typeof value === "undefined") {
return new Date();
return new Date() as TRes;
}

if (value === null) {
return null;
return null as TRes;
}

return new Date(value);
};
return new Date(value as any) as TRes;
}

public toJsDate = (value: Date) => {
return value;
Expand Down
21 changes: 14 additions & 7 deletions packages/date-fns/src/date-fns-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,15 +85,15 @@ const defaultFormats: DateIOFormats = {
year: "yyyy",
};

export default class DateFnsUtils implements IUtils<Date> {
export default class DateFnsUtils implements IUtils<Date, Locale> {
public lib = "date-fns";
public locale?: Locale;
public formats: DateIOFormats;

constructor({
locale,
formats,
}: { formats?: Partial<DateIOFormats>; locale?: Locale } = {}) {
}: { formats?: Partial<DateIOFormats>; locale?: Locale; instance?: any } = {}) {
this.locale = locale;
this.formats = Object.assign({}, defaultFormats, formats);
}
Expand Down Expand Up @@ -288,17 +288,24 @@ export default class DateFnsUtils implements IUtils<Date> {
return setYear(value, count);
};

public date = (value?: any) => {
date<
TArg extends unknown = undefined,
TRes extends unknown = TArg extends null
? null
: TArg extends undefined
? Date
: Date | null
>(value?: TArg): TRes {
if (typeof value === "undefined") {
return new Date();
return new Date() as TRes;
}

if (value === null) {
return null;
return null as TRes;
}

return new Date(value);
};
return new Date(value as string | number) as TRes;
}

public toJsDate = (value: Date) => {
return value;
Expand Down
19 changes: 14 additions & 5 deletions packages/dayjs/src/dayjs-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@ const defaultFormats: DateIOFormats = {
keyboardDateTime24h: "L HH:mm",
};

export default class DayjsUtils<TDate extends Dayjs = Dayjs> implements IUtils<TDate> {
export default class DayjsUtils<TDate extends Dayjs = Dayjs>
implements IUtils<TDate, string>
{
public rawDayJsInstance: typeof defaultDayjs;
public lib = "dayjs";
public dayjs: Constructor<TDate>;
Expand Down Expand Up @@ -119,13 +121,20 @@ export default class DayjsUtils<TDate extends Dayjs = Dayjs> implements IUtils<T
return this.dayjs(value, format, this.locale, true);
};

public date = (value?: any) => {
date<
TArg extends unknown = undefined,
TRes extends unknown = TArg extends null
? null
: TArg extends undefined
? TDate
: TDate | null
>(value?: TArg): TRes {
if (value === null) {
return null;
return null as TRes;
}

return this.dayjs(value);
};
return this.dayjs(value as any) as unknown as TRes;
}

public toJsDate = (value: Dayjs) => {
return value.toDate();
Expand Down
15 changes: 11 additions & 4 deletions packages/hijri/src/hijri-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,20 @@ export default class MomentUtils extends DefaultMomentUtils {
return this.moment(value, format, true).locale("ar-SA");
};

public date = (value?: any) => {
date<
TArg extends unknown = undefined,
TResultingDate extends unknown = TArg extends null
? null
: TArg extends undefined
? Moment
: Moment | null
>(value?: TArg): TResultingDate {
if (value === null) {
return null;
return null as TResultingDate;
}

return this.moment(value).locale("ar-SA");
};
return this.moment(value).locale("ar-SA") as TResultingDate;
}

public isBeforeYear = (date: Moment, value: Moment) => {
return date.iYear() < value.iYear();
Expand Down
15 changes: 11 additions & 4 deletions packages/jalaali/src/jalaali-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,13 +80,20 @@ export default class MomentUtils extends DefaultMomentUtils {
return this.moment(value, format, true).locale("fa");
};

public date = (value?: any) => {
date<
TArg extends unknown = undefined,
TResultingDate extends unknown = TArg extends null
? null
: TArg extends undefined
? Moment
: Moment | null
>(value?: TArg): TResultingDate {
if (value === null) {
return null;
return null as TResultingDate;
}

return this.moment(value).locale("fa");
};
return this.moment(value).locale("fa") as TResultingDate;
}

public isBeforeYear = (date: Moment, value: Moment) => {
return date.jYear() < value.jYear();
Expand Down
26 changes: 17 additions & 9 deletions packages/js-joda/src/js-joda-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ function getChronoUnit(unit?: Unit): ChronoUnit | null {
}
}

export default class JsJodaUtils implements IUtils<Temporal> {
export default class JsJodaUtils implements IUtils<Temporal, Locale> {
lib: "js-joda";
locale?: Locale;
formats: DateIOFormats;
Expand Down Expand Up @@ -158,35 +158,43 @@ export default class JsJodaUtils implements IUtils<Temporal> {
}
}

date(value?: any): Temporal | null {
date<
TArg extends unknown = undefined,
TResultingDate extends unknown = TArg extends null
? null
: TArg extends undefined
? Temporal
: Temporal | null
>(value?: TArg): TResultingDate {
if (value === null) {
return null;
return null as TResultingDate;
}
if (value === undefined) {
return LocalDateTime.now();
return LocalDateTime.now() as TResultingDate;
}

if (typeof value === "string") {
try {
return OPTIONAL_FORMATTER.parse(value, dateOrDateTimeQuery) ?? null;
return (OPTIONAL_FORMATTER.parse(value, dateOrDateTimeQuery) ??
null) as TResultingDate;
} catch (ex) {
if (ex instanceof DateTimeParseException) {
return <Temporal>(<unknown>ex);
return (<Temporal>(<unknown>ex)) as TResultingDate;
}
}
}

if (value instanceof Temporal) {
return value;
return value as TResultingDate;
}

if (value instanceof Date) {
const instant = Instant.ofEpochMilli(value.valueOf());
return LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
return LocalDateTime.ofInstant(instant, ZoneId.systemDefault()) as TResultingDate;
}

/* istanbul ignore next */
return null;
return LocalDateTime.now() as TResultingDate;
}

isNull(date: Temporal | null): boolean {
Expand Down
27 changes: 19 additions & 8 deletions packages/luxon/src/luxon-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const defaultFormats: DateIOFormats = {
year: "yyyy",
};

export default class LuxonUtils implements IUtils<DateTime> {
export default class LuxonUtils implements IUtils<DateTime, string> {
public lib = "luxon";
public locale: string;
public formats: DateIOFormats;
Expand All @@ -44,25 +44,36 @@ export default class LuxonUtils implements IUtils<DateTime> {
this.formats = Object.assign({}, defaultFormats, formats);
}

public date = (value?: any) => {
date<
TArg extends unknown = undefined,
TRes extends unknown = TArg extends null
? null
: TArg extends undefined
? DateTime
: DateTime | null
>(value?: TArg): TRes {
if (typeof value === "undefined") {
return DateTime.local();
return DateTime.local() as TRes;
}

if (value === null) {
return null;
return null as TRes;
}

if (typeof value === "string") {
return DateTime.fromJSDate(new Date(value), { locale: this.locale });
return DateTime.fromJSDate(new Date(value), { locale: this.locale }) as TRes;
}

if (DateTime.isDateTime(value)) {
return value;
return value as TRes;
}

return DateTime.fromJSDate(value, { locale: this.locale });
};
if (value instanceof Date) {
return DateTime.fromJSDate(value, { locale: this.locale }) as TRes;
}

return DateTime.local() as TRes;
}

public toJsDate = (value: DateTime) => {
return value.toJSDate();
Expand Down
Loading

0 comments on commit 50487b8

Please sign in to comment.