Created
October 3, 2020 23:22
-
-
Save phenomnomnominal/d0c52eb4c84f8adaa83a87f78beb9c46 to your computer and use it in GitHub Desktop.
TypeScript Template Types Date Validator
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
// Check it out here: | |
https://www.typescriptlang.org/play?ts=4.1.0-dev.20201001#code/C4TwDgpgBAcgrgWwEYQE4GcoF4oHIAMuUAPngIxGm4BMleAzHbgCxMCsTAbEwOxMAcTAJy4A3AChQkWAHsAdgC00M7FACiADwDGAGzgATCAB54yNOgA0eQgD4Jk8NACaEAIapVAAwAkAb1MoGAC+fgHmIf6IgegRYcGeElLQALLywAAWmDie+KHySqgyQZ4k5ISluGQUFWS0iY5QACKuIFlQPr4ETNVUtLH5ysUV9OVU9BT2SVAAEjJwGF65kWbxpZ5koVHhJb2jeNQ9+7QV1IwnrPXSCvIQs-NtMAOFa0uPioM7Zd2HlbQO0skAJZyODACBtDpdGpMY5jJisCocWJbeKXaAAZQgWnk+jaQJBYPQaKgQJ0OkB6CxOIhmxWMVp0WRdOKkwa1zkEAACqgIAAzQEaVS4ADUTAAtGJxP9oM0wZz3JS1KhCqgjMlwehXABzaAQDRguS4qDoYCoYFamyqXxQNAqgBcJI12ugQVZ0llEAAKoCEMZxFAA1BPTb9RBDZgTWa5FrxJacP7A8G9QajR1gby0E1XGDvb6ggo-OnM+yIEMAPxQBOBwPyjAQD25iAlowNn0QKwly12qtBkMpzBpuQZjwe8s96u1ymt32PZseruV6seycQJUqoyeacQB0ASTkADdXOT9Fmc22HX5PcU7FKpiut82e1v0aa+2GjZHzRYeyWXx5k++Eaml+PYrvoW6qPe2Zem2s43C20GNn+NjfhOCoQPoJaQehza-qaNixthdbgYhbZvuGp4wb6f5QGW441uhmE3ORRp4R4dHVpxgYdGBW75n4YElkM3ZcQGgnMSJDHEVubrQFBZ4zjIj5LqRilsSxQFRjGcaLoGW5wRyNEARRg7DpRQSeoWQ6Zo25a6Vx8lUcYHpWI2XZPqpEAGRARmhiZVlmaOJQcaJjkIWCC4eXK6FrjIqqeI5jbebuB5HoCJ4ehevj6UpNx-teslQIlbZGFFPmvsZH7AdGqGJm2vn9sa1VarVYmMR6RFTtB4XlagKGgYxjadU5RhIfhhE4Lx0EaZRNEVvRbXEUNlWYGN7H2aJAY8e10EWQJg1tsJC1FQdvpQJJi2UiRYKFWFZUNYBTVaRNG0eg9-m+EWHguO4+VigFmapHIGR-QDI4tOg+XBcdK4-agQMZM0IBGHDf5WAj6Ro1mrTIed90VX5qZg1AqOmkE-2fdZHgY1DtEw+hcMYyjbioFjNP4XjKlgu9ROU2ZpOoGOm2wyzzO-RzF2USusXxY5KWHselFZW9ZOeDe0onXWjNpOkSOldWAszZ+NU9uz-6E5pIEqSAPOWybaHEXDw1w2LrP4a1mtXRjw1M2b-UO1dSPDXrSPId+OlgU7K0kyzc0bQHGHe9HZu0fHoU7SAM2h6+82bZtHQC+Tfhm0X2UtLTkvCxnnPp8R3uS5HLP2BrIvuEzPaG9HxstabOu209VtSVdTuTQzosC-7Q+JzrPs62qffuy9jfuDNhu57XXsz8nC-scd1YF7HZMUyXJSV1P+j1wNjtN7eDSt6qHeH+bjXd+HqiP+Lz+PU769cYbDplWlsqOKG577yzSieOGWVC5q1uuhdu1YU5d2am-eMiCd4zQxpgX+nEU4AK5lyGKwDZbwJ1uAxWGMson3VnedCesPI2wJi-FBL0GH9yRtgtOAZs4eHwXpaCQD1wJToS0ch6UlZQD8Dwgqt9pArmUoGdSyDno6R-HlJhj0Sx3AWCFLi6k+EBiURbdofgSzcj5AKCIX0oAAHleS8kpMAOy9M6wljsQ4iAwAjDuMcZaaOPjPF0zzoo9RvCXGUjcfYxx3iomePctWIxjVTKZgCU44KXDPZNhuKkmJHjgB+OMakoJwSoD6PCVkjkOTUnxP4dFOsMtQE4RuGIk8JYspsWvLIuSTTKmxK8T2VJ-dX6sOrIMjRH1rHaJiHaYm+JQTgiFhvW4cwMBzMJEYKZ6NgTzPQDUgMYyv4TKpjMFZMRoZVzrFMjZpy9lSyIUI+R2S+ktNsc8yRvgDkyJbuhRs+s6rUXGVVFR79qxrRmskjwUz8ozL5oDbZhJoXE0xNicM+UAB0szARkgpLTXRnEVxTLWeCZF1JSTknQNc+4bN4XEtNFYElqK6UkixeS3GkswXRwhScqlZMYXWKJZDXlSKqSMsFucpZhKaWQxFbiSlGBqUElpagelMrBV9RrgGDlxiuVQqFbC6mUrcXlMlYqilurlXMtNWywB9yQHCLrI2F5jr3lrQKnAy5pyBUMtxGSikfyAzmqNiwxBhrAV2x7tWb1aqg1aQ9r66NyjB6XQwlM4aVzzWT2TRfKVPspVqlDX1D2YEo3DSjUYKNYcr5exZRSXN2KKXxuQiM8+qbo6BrxQnbNprMEFuKcE4tqqZoVpznvJZ2b609vrXNUdwSOjmqCDCr1erh2Cwxb4RtqsNUlKzfGrdFyrolrPjunNDdGJTPdZSE1Oyy09kDYm+2gYl2HKBUmqAK6Y2vrAqm0eHr7hyrVZmzJXadm5tNfmq1i9O0lp-ZSMtK6CKqM7a24x7bynAcJD2iDu9t0DpRUaaO76O0lLnacxF66C0Lr8Cuo6OHGKHrQwKrdX7TkXuWfcAV-ruXyrDQPB9AYn0fr40B79mT02kcg+fRjMGIAcafQhkFLbTkzVQ-uxOObk69qI1xEjPLBaLoo6fBjJ6q0ppY100TpzOPaKGSwxDgZrM8dTTg6sDneGvQEbakhv6MAvO0VlVzXzaF1g46bXt96e52f42F4xjHnOPt7QYu59TiGNOC1Kl5AqqEGZoXfdCN7I2qps7G5tAZ30EcHXF0rhXXyJeXJ51LsHVUvKjVlajsCpTfLS-WzjG7n3htQRtXrk7yUVYyUN2rHnksPPgTW9AGXZtNfeb1wLDR8Qj0or8gg+Btu4BvFMZIrgNDra3EYXAQhzsiD2w0OGMtVAncqBdy7xI4ZYRwPdsgF2FAUCu9IF7NxtF3c8qdj752FD4G+89lmWjPU5re0Dh7oPwd2jIBwH7zgoc3BgBALU2ZAT7mgHDhSxgEdCAUGKcHu3IfuGh+xqVWOcfADxwTjbJUSdk6RyjynGs-sck5DIdAgJGf48B0T4Hn3hTUFYGjmO1P-sw9NXzgXQvmfvfFxz1HVP4Yz0JyNEn5PGDS+1sDdIt2debZB0IYU+ADea73ArdKGMZbogQEeHQIvdcW-J7YW3qVjyO+IQAIUBFqd35uLtijIDb7nLMMavZZ76MX539dfa51MI3GQaceDN6zz31uwcQ+j23HWJZ6e4+F9nhPeu8-k4L2nmPxebiK8F0z0POfw954l1LzXGMkam-j8T3P9ArdR7r0X43QcK8D-b-QfXqfrv1+N3biBvfiHO9d63yvg+vdz9+wvjIS-jwr5VEHkPk-E9CH12KegtBDd791i0OPquk-W+T7X+fY-EYP7l-MDfU-n8z7zwp1vw-3vxABL2xzLxV3hy32ryAO7x1iRjMX52b3L373P0vw70lx33RxAKRm0T7yfwvxf2t09DgMLy13HxaG0SJV-3QOIPoFILIDtB22AIoM-xAGoJpSdxdzJFoKrwAIYI52wJlzYNAM4MVRlhPz4JgMEKYM4G93IJ7yoJWSJUf2gOn310YLtDYFJzf131wOUPmFUO-yzzQP4M0KRx0LBxH3f1ELwJUJpXAIZxbzP3MJIMsNJ3Jxv3gMoI4IcMVSQKVxcLMJkK0KsIlxsP0LsMMPhhpW9WkI0PcKYJ0O0Ke0UIQJiKJW9W4PX1cNCI8OYOEPTzEP8PmWyMD2DwSP-wsOSKEDtHkKKLv3sKMLiJlTUNFzcNkNSLtGYHwAUG4FYKUL8JaMVW9UzyqKIIELCLqN6LBz4EGIyOGNiNGLaJMNL2VwmIwK6JSNmPJy73SN8PELKNWI5G0Sbw2LyMSO2JmL6Ktw1wOPYKOO5hlV9U2PoOmNSLRW2wUNH2iKWKyJeJrRyN4MuOqKSO6J0K+MaIMP+NaLw19UkMqNBMmJqIhKEDRTIG+OhL+KeJ8kBOxXaI9yuI+MhO+IUHmJ8MeNKOePhJrXGORK2JJPRLJPwEEAWMOOpLxNpIJMxwgIuJCOJIKNJO23ZzSN+KGNxO9V9UCJQKgI6PyNqM+LJOFExK5yAA | |
type Numbers = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'; | |
type NonZero = Exclude<Numbers, '0'>; | |
type Year = `${Numbers}${Numbers}${Numbers}${Numbers}`; | |
type Months = `0${NonZero}` | '10' | '11' | '12'; | |
type Days = `${'0' | '1' | '2'}${NonZero}` | '30' | '31'; | |
type Hours = `0${Numbers}` | `1${Numbers}` | '20' | '21' | '22' | '23' | '24'; | |
type ZoneHours = NonZero | `0${NonZero}` | '10' | '11' | '12' | |
type Minutes = `${'0' | '1' | '2' | '3' | '4' | '5'}${Numbers}`; | |
type Seconds = Minutes; | |
type Milliseconds = `${Numbers}${Numbers}${Numbers}`; | |
type ZonePrefix = '+' | '-'; | |
type DateParseError<Message extends string> = { error: Message }; | |
type DateTime< | |
T extends string | |
> = | |
T extends `${infer DateTime}Z${infer Zone}` ? | |
ParseDateTimeZone<DateTime, Zone> : | |
T extends `${infer Date}` ? | |
ParseDateTimeNoZone<Date> : | |
DateParseError<`DateTime: Invalid DateTime: ${T}`>; | |
type ParseDateTimeZone< | |
DateTimeStr extends string, | |
ZoneStr extends string, | |
ParsedDateTime = ParseDateTimeNoZone<DateTimeStr>, | |
ParsedZone = ParseZone<ZoneStr> | |
> = ParsedDateTime extends DateTimeStr ? | |
ParsedZone extends ZoneStr ? | |
`${ParsedDateTime}Z${ParsedZone}` : | |
ParsedZone : | |
ParsedDateTime; | |
type ParseDateTimeNoZone< | |
DateTimeNoZoneStr extends string | |
> = | |
DateTimeNoZoneStr extends `${infer Date}T${infer Time}` ? | |
ParseDateTime<Date, Time> : | |
DateTimeNoZoneStr extends `${infer Date}` ? | |
ParseDate<Date> : | |
DateParseError<`ParseDateTimeNoZone: Invalid Date: ${DateTimeNoZoneStr}`>; | |
type ParseDateTime< | |
DateStr extends string, | |
TimeStr extends string, | |
ParsedDate = ParseDate<DateStr>, | |
ParsedTime = ParseTime<TimeStr> | |
> = ParsedDate extends DateStr ? | |
ParsedTime extends TimeStr ? | |
`${ParsedDate}T${ParsedTime}` : | |
ParsedTime : | |
ParsedDate; | |
type ParseDate< | |
DateStr extends string | |
> = | |
DateStr extends `${infer YearStr}-${infer MonthStr}-${infer DaysStr}` ? | |
ParseYearMonthDay<YearStr, MonthStr, DaysStr> : | |
DateStr extends `${infer YearStr}-${infer MonthStr}` ? | |
ParseYearMonth<YearStr, MonthStr> : | |
DateStr extends `${infer YearStr}` ? | |
ParseYear<YearStr> : | |
DateParseError<`ParseDate: Invalid Date: ${DateStr}`>; | |
type ParseYearMonthDay< | |
YearStr extends string, | |
MonthStr extends string, | |
DayStr extends string, | |
ParsedYear = ParseYear<YearStr>, | |
ParsedMonth = ParseMonth<MonthStr>, | |
ParsedDay = ParseDay<DayStr>, | |
> = ParsedYear extends YearStr ? | |
ParsedMonth extends MonthStr ? | |
ParsedDay extends DayStr ? | |
`${YearStr}-${MonthStr}-${DayStr}` : | |
ParsedDay : | |
ParsedMonth : | |
ParsedYear; | |
type ParseYearMonth< | |
YearStr extends string, | |
MonthStr extends string, | |
ParsedYear = ParseYear<YearStr>, | |
ParsedMonth = ParseMonth<MonthStr>, | |
> = ParsedYear extends YearStr ? | |
ParsedMonth extends MonthStr ? | |
`${YearStr}-${MonthStr}` : | |
ParsedMonth : | |
ParsedYear; | |
type ParseYear< | |
YearStr extends string, | |
> = | |
YearStr extends Year ? | |
YearStr : | |
DateParseError<`ParseYear: Invalid Year: ${YearStr}`>; | |
type ParseMonth< | |
MonthStr extends string, | |
> = | |
MonthStr extends Months ? | |
MonthStr : | |
DateParseError<`ParseMonth: Invalid Month: ${MonthStr}`>; | |
type ParseDay< | |
DayStr extends string, | |
> = | |
DayStr extends Days ? | |
DayStr : | |
DateParseError<`ParseDay: Invalid Date: ${DayStr}`>; | |
type ParseZone< | |
ZoneStr extends string | |
> = | |
ZoneStr extends ZoneHours ? | |
ZoneStr : | |
ZoneStr extends `${ZonePrefix}${infer Offset}` ? | |
ParseZoneOffset<Offset> extends Offset ? | |
ZoneStr : | |
ParseZoneOffset<Offset> : | |
ZoneStr extends `${infer Offset}` ? | |
ParseZoneOffset<Offset> extends Offset ? | |
ZoneStr : | |
ParseZoneOffset<Offset> : | |
DateParseError<`ParseZone: Invalid Zone: ${ZoneStr}`> | |
type ParseZoneOffset< | |
OffsetStr extends string, | |
> = | |
OffsetStr extends `${infer Hours}:${infer Minutes}` ? | |
ParseHoursMinutes<Hours, Minutes> : | |
OffsetStr extends `${infer Hours}` ? | |
ParseHours<Hours> : | |
DateParseError<`ParseZoneOffset: Invalid Offset: ${OffsetStr}`>; | |
type ParseTime< | |
TimeStr extends string | |
> = | |
TimeStr extends `${infer HoursStr}:${infer MinutesStr}:${infer SecondsStr}.${infer MillisStr}` ? | |
ParseHoursMinutesSecondsMillis<HoursStr, MinutesStr, SecondsStr, MillisStr> : | |
TimeStr extends `${infer HoursStr}:${infer MinutesStr}:${infer SecondsStr}` ? | |
ParseHoursMinutesSeconds<HoursStr, MinutesStr, SecondsStr> : | |
TimeStr extends `${infer HoursStr}:${infer MinutesStr}` ? | |
ParseHoursMinutes<HoursStr, MinutesStr> : | |
DateParseError<`ParseTime: Invalid Time: ${TimeStr}`>;; | |
type ParseHoursMinutesSecondsMillis< | |
HoursStr extends string, | |
MinutesStr extends string, | |
SecondsStr extends string, | |
MillisStr extends string, | |
ParsedHours = ParseHours<HoursStr>, | |
ParsedMinutes = ParseMinutes<MinutesStr>, | |
ParsedSeconds = ParseSeconds<SecondsStr>, | |
ParsedMillis = ParseMillis<MillisStr> | |
> = | |
ParsedHours extends HoursStr ? | |
ParsedMinutes extends MinutesStr ? | |
ParsedSeconds extends SecondsStr ? | |
ParsedMillis extends MillisStr ? | |
`${HoursStr}:${MinutesStr}:${SecondsStr}.${MillisStr}` : | |
ParsedMillis : | |
ParsedSeconds : | |
ParsedMinutes : | |
ParsedHours; | |
type ParseHoursMinutesSeconds< | |
HoursStr extends string, | |
MinutesStr extends string, | |
SecondsStr extends string, | |
ParsedHours = ParseHours<HoursStr>, | |
ParsedMinutes = ParseMinutes<MinutesStr>, | |
ParsedSeconds = ParseSeconds<SecondsStr> | |
> = | |
ParsedHours extends HoursStr ? | |
ParsedMinutes extends MinutesStr ? | |
ParsedSeconds extends SecondsStr ? | |
`${HoursStr}:${MinutesStr}:${SecondsStr}` : | |
ParsedSeconds : | |
ParsedMinutes : | |
ParsedHours; | |
type ParseHoursMinutes< | |
HoursStr extends string, | |
MinutesStr extends string, | |
ParsedHours = ParseHours<HoursStr>, | |
ParsedMinutes = ParseMinutes<MinutesStr> | |
> = | |
ParsedHours extends HoursStr ? | |
ParsedMinutes extends MinutesStr ? | |
`${HoursStr}:${MinutesStr}` : | |
ParsedMinutes : | |
ParsedHours; | |
type ParseHours< | |
HourStr extends string, | |
> = | |
HourStr extends Hours ? | |
HourStr : | |
DateParseError<`ParseHours: Invalid Hour: ${HourStr}`>; | |
type ParseMinutes< | |
MinutesStr extends string, | |
> = | |
MinutesStr extends Minutes ? | |
MinutesStr : | |
DateParseError<`ParseMinutes: Invalid Minutes: ${MinutesStr}`>; | |
type ParseSeconds< | |
SecondsStr extends string, | |
> = | |
SecondsStr extends Seconds ? | |
SecondsStr : | |
DateParseError<`ParseSeconds: Invalid Seconds: ${SecondsStr}`>; | |
type ParseMillis< | |
MillisStr extends string, | |
> = | |
MillisStr extends Milliseconds ? | |
MillisStr : | |
DateParseError<`ParseMillis: Invalid Milliseconds: ${MillisStr}`>; | |
type MinYear = DateTime<'0000'>; | |
type MaxYear = DateTime<'9999'>; | |
type YearError = DateTime<'19999'>; | |
type YearZone = DateTime<'1999Z1'>; | |
type YearZoneHour = DateTime<'1999Z01'>; | |
type YearZoneHoursMinutes = DateTime<'1999Z01:15'>; | |
type YearZoneNegative = DateTime<'1999Z-01'>; | |
type YearZoneHoursMinutesNegative = DateTime<'1999Z-01:15'>; | |
type YearZonePositive = DateTime<'1999Z+24'>; | |
type YearZoneHoursMinutesPositive = DateTime<'1999Z+01:15'>; | |
type YearMonth = DateTime<'1999-03'>; | |
type YearMonthError = DateTime<'1999+03'>; | |
type YearInvalidMonthErrorSmall = DateTime<'1999-00'>; | |
type YearInvalidMonthErrorBig = DateTime<'1999-13'>; | |
type YearMonthZone = DateTime<'1999-03Z1'>; | |
type YearMonthZoneHour = DateTime<'1999-03Z01'>; | |
type YearMonthZoneNegative = DateTime<'1999-03Z-01'>; | |
type YearMonthZonePositive = DateTime<'1999-03Z+24'>; | |
type YearMonthDayError = DateTime<'1999-03+03'>; | |
type YearMonthDay = DateTime<'1999-03-03'>; | |
type YearMonthInvalidDayErrorSmall = DateTime<'1999-03-00'>; | |
type YearMonthInvalidDayErrorBig = DateTime<'1999-03-32'>; | |
type YearMonthDayZone = DateTime<'1999-03-03Z1'>; | |
type YearMonthDayZoneHour = DateTime<'1999-03-03Z01'>; | |
type YearMonthDayZoneNegative = DateTime<'1999-03-03Z-01'>; | |
type YearMonthDayZonePositive = DateTime<'1999-03-03Z+24'>; | |
type YearMonthDayHourError = DateTime<'1999-03-03T01'>; | |
type YearMonthDayHourMinute = DateTime<'1999-03-03T01:00'>; | |
type YearMonthDayHourMinuteErrorSmall = DateTime<'1999-03-03T01:1'>; | |
type YearMonthDayHourMinuteErrorBig = DateTime<'1999-03-03T01:60'>; | |
type YearMonthDayHourMinuteZone = DateTime<'1999-03-03T01:59Z1'>; | |
type YearMonthDayHourMinuteZoneHour = DateTime<'1999-03-03T01:59Z03'>; | |
type YearMonthDayHourMinuteZoneNegative = DateTime<'1999-03-03T01:59Z-02'>; | |
type YearMonthDayHourMinuteZonePositive = DateTime<'1999-03-03T01:59Z+23'>; | |
type YearMonthDayHourMinuteSecond = DateTime<'1999-03-03T01:59:59'>; | |
type YearMonthDayHourMinuteSecondErrorSmall = DateTime<'1999-03-03T01:59:0'>; | |
type YearMonthDayHourMinuteSecondErrorBig = DateTime<'1999-03-03T01:59:60'>; | |
type YearMonthDayHourMinuteSecondZone = DateTime<'1999-03-03T01:59:40Z6'>; | |
type YearMonthDayHourMinuteSecondZoneHour = DateTime<'1999-03-03T01:59:40Z07'>; | |
type YearMonthDayHourMinuteSecondZoneHourNegative = DateTime<'1999-03-03T01:59:40Z-04'>; | |
type YearMonthDayHourMinuteSecondZoneHourPositive = DateTime<'1999-03-03T01:59:40Z+05'>; | |
type YearMonthDayHourMinuteSecondMilli = DateTime<'1999-03-03T01:59:59.000'>; | |
type YearMonthDayHourMinuteSecondMilliErrorSmall = DateTime<'1999-03-03T01:59:59.0'>; | |
type YearMonthDayHourMinuteSecondMilliErrorBig = DateTime<'1999-03-03T01:59:59.1000'>; | |
type YearMonthDayHourMinuteSecondMilliZone = DateTime<'1999-03-03T01:59:59.000Z7'>; | |
type YearMonthDayHourMinuteSecondMilliZoneHour = DateTime<'1999-03-03T01:59:59.000Z08'>; | |
type YearMonthDayHourMinuteSecondMilliZoneNegative = DateTime<'1999-03-03T01:59:59.000Z-09'>; | |
type YearMonthDayHourMinuteSecondMilliZonePositive = DateTime<'1999-03-03T01:59:59.000Z+10'>; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Wow! Cool! May be publish it as npm-package to
@types/ParseDate
?