[作者文章链接](一道字节的 TS 体操面试真题前天,小册群友问了我一个 TS 体操问题,说是面字节时遇到的。 今天又催了一下: 面试题是 - 掘金 (juejin.cn))
今天晚上没啥事逛逛掘金,看到一道ts类型体操的面试题,又看了看作者的解法,感觉好牛...
就我这种ts体操玩起来很吃力的 月薪3000的小菜鸡,想试着学习一下,于是复制到自己的vscode。 发现这个ts类型稍微有那么一点点问题。。。
这里没有报错。YY-MM/DD 这个 分隔符 不一样...但是通过检测了
const aaaa: FormatDate<'YY-MM/DD'> = '2023-01-02';
看到这个问题,我有点小强迫症,不解决心里难受,于是直接开怼这道题。由于我很菜,看作者的ts看不太懂,所以只能自己解。
于是作为月薪3000又很菜的小前端的我,愣是花了2个多小时终于解完了,头皮差点薅没了...
// 三个时间的标识
type Type = 'MM' | 'DD' | 'YY';
// 获取分隔符,所有分隔符必须相等 才能获取,否则never
type Separator<I extends any> = I extends `${Type}${infer A}${Type}${infer B}${Type}`
? A extends B
? I extends `${infer C}${A}${infer D}${A}${infer E}`
? C extends D | E
? never
: D extends E
? never
: A
: never
: never
: never;
type Num = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;
// 通过 Type标识 判断,否则never
type DD<T> = T extends 'DD' ? `${0 | 1 | 2}${Num}` | `30` | `31` : never;
type MM<T> = T extends 'MM' ? `${0}${Num}` | `10` | `11` | `12` : never;
type YY<T> = T extends 'YY' ? `${19 | 20}${Num}${Num}` : never;
type FormatDate<I extends string> = I extends `${infer A}${Separator<I>}${infer B}${Separator<I>}${infer C}`
? `${DD<A> | MM<A> | YY<A>}${Separator<I>}${DD<B> | MM<B> | YY<B>}${Separator<I>}${DD<C> | MM<C> | YY<C>}`
: never;
// 测试
let data1: FormatDate<'MM-DD-YY'> = '11-21-1900'; //通过
let data2: FormatDate<'MM-YY-DD'> = '11-2010-21'; //通过
let data3: FormatDate<'MM-YY-DD'> = '11-2099-21'; //通过
//通过 任意分隔符也可以
//我没有对 分隔符 做限制,有需要自己改....
let data4: FormatDate<'MM---YY---DD'> = '11---2099---21';
let data11: FormatDate<'MM-DD/YY'> = '11-21-1900'; //报错 分隔符报错
let data22: FormatDate<'MM.DD/YY'> = '11.21/1900'; //报错 分隔符报错
let data33: FormatDate<'YY-DD-MM'> = '11-21-1900'; //报错 时间位置错误
let data44: FormatDate<'MM-DD-DD'> = '11-01-21'; //报错 必须同时存在 MM,DD,YY
let data55: FormatDate<'MM-YY-DD'> = '11-2100-21'; //通过 YY超过限制
let data66: FormatDate<'MM-DD-YY'> = '111-21-1900'; //报错
我自己试了一下,解决了问题,不知道会不会有其他问题...有的话,请留言给菜鸡的我...