Repository: apache/superset
File: superset-frontend/packages/superset-ui-core/src/utils/dates.ts (TypeScript)

Code before:
import timezone from 'dayjs/plugin/timezone';
import calendar from 'dayjs/plugin/calendar';
import relativeTime from 'dayjs/plugin/relativeTime';
import customParseFormat from 'dayjs/plugin/customParseFormat';
import duration from 'dayjs/plugin/duration';
import updateLocale from 'dayjs/plugin/updateLocale';
import localizedFormat from 'dayjs/plugin/localizedFormat';

dayjs.extend(utc);
dayjs.extend(timezone);
dayjs.extend(calendar);
dayjs.extend(relativeTime);
dayjs.extend(customParseFormat);
dayjs.extend(duration);
dayjs.extend(updateLocale);
dayjs.extend(localizedFormat);

dayjs.updateLocale('en', {
  invalidDate: 'Invalid date',
});

// Extended Dayjs instance type with plugin methods
export interface ExtendedDayjs extends Dayjs {
  utc(keepLocalTime?: boolean): ExtendedDayjs;
  local(): ExtendedDayjs;
  isUTC(): boolean;
  tz(timezone?: string, keepLocalTime?: boolean): ExtendedDayjs;
  fromNow(withoutSuffix?: boolean): string;
  toNow(withoutSuffix?: boolean): string;
  from(compared: ConfigType, withoutSuffix?: boolean): string;
  to(compared: ConfigType, withoutSuffix?: boolean): string;
  calendar(referenceTime?: ConfigType, formats?: object): string;
}

// Type for dayjs factory with all plugins loaded
type DayjsWithPlugins = {
  (config?: ConfigType, format?: string, strict?: boolean): ExtendedDayjs;
  utc(config?: ConfigType, format?: string, strict?: boolean): ExtendedDayjs;
  tz: {
    (input?: ConfigType, timezone?: string): ExtendedDayjs;
    guess(): string;
    setDefault(timezone?: string): void;
  };
  updateLocale(locale: string, config: object): object;
} & Omit<typeof dayjs, 'utc' | 'tz'>;

export const extendedDayjs = dayjs as unknown as DayjsWithPlugins;
export type { Dayjs, ConfigType };

export const fDuration = function (
  t1: number,

Review comment (suggestion):
we should add comments to help future people understanding what `dayjs` plugin that these methods got defined, so that when they extend with new plugin, they can expand this interface further.


```suggestion
  // Derived from dayjs/plugin/utc.
  utc(keepLocalTime?: boolean): ExtendedDayjs;
```

Code after:
import timezone from 'dayjs/plugin/timezone';
import calendar from 'dayjs/plugin/calendar';
import relativeTime from 'dayjs/plugin/relativeTime';
import customParseFormat from 'dayjs/plugin/customParseFormat';
import duration from 'dayjs/plugin/duration';
import updateLocale from 'dayjs/plugin/updateLocale';
import localizedFormat from 'dayjs/plugin/localizedFormat';

dayjs.extend(utc);
dayjs.extend(timezone);
dayjs.extend(calendar);
dayjs.extend(relativeTime);
dayjs.extend(customParseFormat);
dayjs.extend(duration);
dayjs.extend(updateLocale);
dayjs.extend(localizedFormat);

dayjs.updateLocale('en', {
  invalidDate: 'Invalid date',
});

// Extended Dayjs instance type with plugin methods.
// When extending dayjs with a new plugin, add its instance methods here.
export interface ExtendedDayjs extends Dayjs {
  // Derived from dayjs/plugin/utc
  utc(keepLocalTime?: boolean): ExtendedDayjs;
  local(): ExtendedDayjs;
  isUTC(): boolean;
  // Derived from dayjs/plugin/timezone
  tz(timezone?: string, keepLocalTime?: boolean): ExtendedDayjs;
  // Derived from dayjs/plugin/relativeTime
  fromNow(withoutSuffix?: boolean): string;
  toNow(withoutSuffix?: boolean): string;
  from(compared: ConfigType, withoutSuffix?: boolean): string;
  to(compared: ConfigType, withoutSuffix?: boolean): string;
  // Derived from dayjs/plugin/calendar
  calendar(referenceTime?: ConfigType, formats?: object): string;
}

// Type for dayjs factory with all plugins loaded.
// When extending dayjs with a new plugin, add its static methods here.
type DayjsWithPlugins = {
  (config?: ConfigType, format?: string, strict?: boolean): ExtendedDayjs;
  // Derived from dayjs/plugin/utc
  utc(config?: ConfigType, format?: string, strict?: boolean): ExtendedDayjs;
  // Derived from dayjs/plugin/timezone
  tz: {
    (input?: ConfigType, timezone?: string): ExtendedDayjs;
    guess(): string;
    setDefault(timezone?: string): void;
  };