Skip to content
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

Closed
wants to merge 11 commits into from
100 changes: 0 additions & 100 deletions index.d.ts

This file was deleted.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"scripts": {
"test": "TZ=Pacific/Auckland npm run test-tz && TZ=Europe/London npm run test-tz && npm run test-tz && jest",
"test-tz": "jest test/timezone.test --coverage=false",
"lint": "./node_modules/.bin/eslint src/* test/* build/*",
"lint": "./node_modules/.bin/eslint src/*.js test/*.js build/*.js",
"prettier": "prettier --write \"docs/**/*.md\"",
"babel": "cross-env BABEL_ENV=build babel src --out-dir esm --copy-files",
"build": "cross-env BABEL_ENV=build node build && npm run size",
Expand Down
114 changes: 114 additions & 0 deletions src/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
declare const dayjs: dayjs;
export = dayjs;

declare namespace dayjs {
type ConfigType = string | number | Date | Dayjs

type OptionType = { locale: string }

type UnitTypeShort = 'd' | 'M' | 'y' | 'h' | 'm' | 's' | 'ms'
type UnitTypeSingular = 'millisecond' | 'second' | 'minute' | 'hour' | 'day' | 'week' | 'month' | 'quarter' | 'year' | 'date' | UnitTypeShort;
type UnitTypePlural = 'milliseconds' | 'seconds' | 'minutes' | 'hours' | 'days' | 'weeks' | 'months' | 'quarters' | 'years' | 'dates'
type UnitType = UnitTypeSingular | UnitTypePlural

type OpUnitTypeShort = 'w'
type OpUnitType = UnitType | "week" | OpUnitTypeShort;

type PluginFunc<TPlugin> = (option: ConfigType, dayjsClass: InstanceType<Dayjs>, dayjsFactory: dayjs) => void;

/**
* Branding for static plugins, to enable better type inference.
* `extend` from this to make the plugin static
*/
interface StaticPlugin {
__staticPlugin: never;
}
}

interface dayjs<TPlugin = {}> {
(config?: dayjs.ConfigType, option?: dayjs.OptionType): {} extends TPlugin
? Dayjs
: Dayjs & TPlugin;

extend<UPlugin extends object>(
plugin: dayjs.PluginFunc<UPlugin>,
option?: dayjs.ConfigType
): UPlugin extends dayjs.StaticPlugin ? (dayjs<TPlugin> & UPlugin) : dayjs<TPlugin & UPlugin>;
locale(arg1: any, arg2?: any): string;
isDayjs(d: any): d is Dayjs;
unix(t: number): Dayjs;
}

declare interface DayjsObject {
years: number;
months: number;
date: number;
hours: number;
minutes: number;
seconds: number;
milliseconds: number;
}

declare class Dayjs {
constructor(config?: dayjs.ConfigType);

clone(): Dayjs;

isValid(): boolean;

year(): number;

month(): number;

date(): number;

day(): number;

hour(): number;

minute(): number;

second(): number;

millisecond(): number;

set(unit: dayjs.UnitType, value: number): Dayjs;

add(value: number, unit: dayjs.OpUnitType): Dayjs;

subtract(value: number, unit: dayjs.OpUnitType): Dayjs;

startOf(unit: dayjs.OpUnitType): Dayjs;

endOf(unit: dayjs.OpUnitType): Dayjs;

format(template?: string): string;

diff(dayjs: ConfigType, unit: OpUnitType, float?: boolean): number

valueOf(): number;

unix(): number;

daysInMonth(): number;

toDate(): Date;

toArray(): number[];

toJSON(): string;

toISOString(): string;

toObject(): DayjsObject;

toString(): string;

isBefore(dayjs: ConfigType, unit?: OpUnitType): boolean

isSame(dayjs: ConfigType, unit?: OpUnitType): boolean

isAfter(dayjs: ConfigType, unit?: OpUnitType): boolean

locale(arg1: any, arg2?: any): Dayjs;
}
8 changes: 8 additions & 0 deletions src/plugin/advancedFormat/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { ConfigType, PluginFunc } from '../../index'

interface AdvancedFormatPlugin {
format(advancedFormat: string): string
}

declare const pluginFn: PluginFunc<AdvancedFormatPlugin>
export default pluginFn
8 changes: 8 additions & 0 deletions src/plugin/buddhistEra/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { ConfigType, PluginFunc } from '../../index'

interface BuddhistEraPlugin {
format(buddhistEraFormat: string): string
}

declare const pluginFn: PluginFunc<BuddhistEraPlugin>
export default pluginFn
8 changes: 8 additions & 0 deletions src/plugin/customParseFormat/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { ConfigType, PluginFunc, StaticPlugin } from '../../index'

interface CustomParseFormatPlugin extends StaticPlugin {
(input: string, format: string): this;
}

declare const pluginFn: PluginFunc<CustomParseFormatPlugin>;
export default pluginFn
8 changes: 8 additions & 0 deletions src/plugin/isBetween/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { ConfigType, PluginFunc, UnitType } from '../../index'

interface IsBetweenPlugin {
isBetween(d1: ConfigType, d2: ConfigType, unit: UnitType): boolean;
}

declare const pluginFn: PluginFunc<IsBetweenPlugin>
export default pluginFn
8 changes: 8 additions & 0 deletions src/plugin/isLeapYear/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { ConfigType, PluginFunc } from '../../index'

interface IsLeapYearPlugin {
isLeapYear(): boolean
}

declare const pluginFn: PluginFunc<IsLeapYearPlugin>
export default pluginFn
11 changes: 11 additions & 0 deletions src/plugin/relativeTime/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { ConfigType, PluginFunc } from '../../index'

interface RelativeTimePlugin {
fromNow(withoutSuffix?: boolean): string
from(compared: ConfigType, withoutSuffix?: boolean): string
toNow(withoutSuffix?: boolean): string
to(compared: ConfigType, withoutSuffix?: boolean): string
}

declare const pluginFn: PluginFunc<RelativeTimePlugin>
export default pluginFn
19 changes: 18 additions & 1 deletion test/index.d.test.ts → test/index.test.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import dayjs from '../src'
import relativeTime from '../src/plugin/relativeTime'
import advancedFormat from '../src/plugin/advancedFormat'
import buddhistEra from '../src/plugin/buddhistEra'
import isLeapYear from '../src/plugin/isLeapYear'
import isBetween from '../src/plugin/isBetween'
import customParseFormat from '../src/plugin/customParseFormat'

dayjs()

Expand Down Expand Up @@ -76,4 +82,15 @@ dayjs().isSame(dayjs(), 'hours')

dayjs().isAfter(dayjs(), 'year')

dayjs('2000-01-01').isLeapYear()
dayjs.extend(relativeTime)().toNow()
dayjs.extend(advancedFormat)().format()
dayjs.extend(buddhistEra)().format()
dayjs.extend(isLeapYear)('2000-01-01').isLeapYear()
dayjs.extend(isBetween)('2010-10-20').isBetween('2010-10-19', dayjs('2010-10-25'), 'year')

const multiplePluginsDayjs = dayjs.extend(relativeTime).extend(isLeapYear)()
multiplePluginsDayjs.toNow()
multiplePluginsDayjs.isLeapYear()

const dayjsWithCustomParseFormat = dayjs.extend(customParseFormat);
dayjsWithCustomParseFormat('05/02/69 1:02:03 PM -05:00', 'MM/DD/YY H:mm:ss A Z');
23 changes: 23 additions & 0 deletions test/plugins.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import MockDate from 'mockdate'
import dayjs from '../src'
import relativeTime from '../src/plugin/relativeTime'
import isLeapYear from '../src/plugin/isLeapYear'

beforeEach(() => {
MockDate.set(new Date())
})

afterEach(() => {
MockDate.reset()
})

it('should allow multiple plugin chaining', () => {
const now = dayjs()
expect(now.fromNow).not.toBeDefined()
expect(now.isLeapYear).not.toBeDefined()

const extendedDayjs = dayjs.extend(relativeTime).extend(isLeapYear)
const extendedNow = extendedDayjs()
expect(typeof extendedNow.fromNow).toBe('function')
expect(typeof extendedNow.isLeapYear).toBe('function')
})