Created
May 12, 2022 15:48
-
-
Save insyri/682868f141425e0263f042cdfd178c63 to your computer and use it in GitHub Desktop.
attempt at making a type level cron validation, licensed under WTFPL, but reference me for inspiration somewhere
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type Length<T extends any[]> = T extends {length: infer L} ? L: never; | |
type BuildTuple<L extends number, T extends any[] = []> = T extends {length: L} ? T: BuildTuple<L, [...T, any]>; | |
type Subtract<A extends number, B extends number> = BuildTuple<A> extends [...(infer U), ...BuildTuple<B>] ? Length<U> : never; | |
// prettier-ignore | |
type To59 = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59; | |
// prettier-ignore | |
type To31 = Exclude<To59, 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59> | |
type To30 = Exclude<To31, 31>; | |
// prettier-ignore | |
type To28 = Exclude<To30, 30 | 29>; | |
// prettier-ignore | |
type To23 = Exclude<To28, 27 | 26 | 25 | 24> | |
// prettier-ignore | |
type To12 = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12; | |
// prettier-ignore | |
type To7 = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7; | |
// prettier-ignore | |
// enum Month { | |
// Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec | |
// } | |
type StringMonth = keyof typeof Month; | |
enum Month { | |
Jan = 31, | |
Feb = 28, | |
Mar = 31, | |
Apr = 30, | |
May = 31, | |
Jun = 30, | |
Jul = 31, | |
Aug = 30, | |
Sep = 31, | |
Oct = 30, | |
Nov = 31, | |
Dec = 30 | |
} | |
// prettier-ignore | |
enum Days { | |
Mon, Tue, Wed, Thu, Fri, Sat, Sun | |
} | |
type StringDay = keyof typeof Days; | |
type Second = To59 | |
type Minute = To59 | |
type Hour = To12 | |
// type DayOfWeek = StringDay | Days; | |
// `second minute hour day month year?` | |
type AnyTimeUnspecific = To59 | To23 | To31 | To12 | To7 | StringMonth | StringDay; | |
type AnyTimeNumber = Exclude<AnyTimeUnspecific, StringMonth | StringDay>; | |
type AnyTimeSpecific<T extends AnyTimeUnspecific> = T; | |
type PutInBetweenSpecific<T1 extends string, S extends string, T2 extends string> = `${T1}${S}${T2}`; | |
// type PutInBetween<S extends string, T extends string> = `${T}${S}${T}`; | |
type Opt<T> = T | '*'; | |
/** | |
* 1 | |
* 1-1 | |
*/ | |
let j = 3; | |
// type Segment<T extends > = `${T}${"" | ''}` | |
// type CronRange<From extends AnyTimeUnspecific, To extends From> = | |
// From extends number ? (To extends number ? (Subtract<From, To> ? PutInBetweenSpecific<'-', `${From}`, `${To}`> : never): never) : | |
// From extends string ? (To extends string ? PutInBetweenSpecific<'-', From, To> : never) : never; | |
type CronRangeNumber<From extends AnyTimeNumber, To extends From> = | |
From extends To12 ? (Subtract<From, To> extends number ? Subtract<From, To> : never) : never; | |
// type SecondRange = CronRange<To12, To12> | |
// let sr: SecondRange = ; | |
// type Range<T extends AnyTimeUnspecific> = | |
// Subtract<T, T> extends number ? Subtract<T, T> : never; | |
// type Interval<T extends AnyTimeUnspecific> = | |
// PutInBetween<'/', AnyTimeSpecific<T>>; | |
// type Listed<T extends AnyTimeUnspecific> = `${AnyTimeSpecific<T>}`; | |
// type VariantOf<T extends AnyTimeUnspecific> = Range<T> | Interval<T> | Listed<T>; | |
/** | |
* ```txt | |
* ┌───── Second (0-59) | |
* │ ┌───── Min (0-59 or *) | |
* │ │ ┌───── Hour (0-23 or *) | |
* │ │ │ ┌───── Day of Month (1-31 or *) | |
* │ │ │ │ ┌───── Month (1-12, Jan-Dec, or *) | |
* │ │ │ │ │ ┌───── Day of Week (1-7, Mon-Sun, or *) | |
* │ │ │ │ │ │ ┌───── Year (optional, default: *) | |
* │ │ │ │ │ │ │ | |
* * * * * * * * | |
* ``` | |
*/ | |
// export type CronDay = `${Second} ${Opt<Minute>} ${Opt<Hour>}`; | |
// export type CronMonth<M extends Month> = `${Opt<DayOf>} ${Opt<Month>}` | |
// type Something<T1 extends number, T2 extends number> = T1 > T2 ? T1 : T2; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment