Created
April 19, 2021 16:37
-
-
Save QuarkGluonPlasma/6093135dd073220afb67eda714d17113 to your computer and use it in GitHub Desktop.
重复字符串的TS类型
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 SpilitStrToTupleByItem<Str extends string, StrItem extends string, TupleRes extends string[] = []> = Str extends `${infer RestStr}${StrItem}` ? | |
SpilitStrToTupleByItem<RestStr,StrItem,[...TupleRes, 'ssh']>: TupleRes; | |
type RepeatCount<Str extends string, StrItem extends string> = Str extends "" ? 0 : SpilitStrToTupleByItem<Str, StrItem>['length']; | |
type RepeatStr<Str extends string, Count extends number, StrItem extends string = Str> = RepeatCount<Str, StrItem> extends Count ? Str : RepeatStr<`${Str}${StrItem}`, Count, StrItem> ; | |
type r = RepeatStr<'Abc', 3>; | |
/* | |
其实思路比较明确,用 js 的话谁都能写出来,但是 ts 可以用的语法就那么多,所以有点别扭,但是也是熟悉了语法都都能写出来那种。 | |
先介绍一下用到的语法 | |
范型用于传参 Type<A, B, C> | |
字符串模版类型用于构造和拆分字符串 `${Str1}${Str2}` `${Str1}${infer Str2}` | |
infer用于推断范型参数类型 Type<Infer T> | |
condition和extends用于条件判断 A extends B? C: D | |
有了这些就能实现这个需求了。 | |
需求是重复一个字符串n次,思路很明确就是 构造字符串,当重复次数达到n的时候就返回当前字符串,否则继续构造,也就是 | |
构造 = RepeatCount<Str, StrItem> extends Count ? Str : 继续构造(构造的方式就是`${Str}${StrItem}`) | |
这里需要把StrItem传递下去,用于拆分字符串判断重复次数。 | |
然后 RepeatCount 就是按照 item 拆分字符串成数组然后计算length,如果是“”直接返回0,否则就返回length | |
计算字符串长度 = Str extends "" ? 0 : SpilitStrToTupleByItem<Str, StrItem>['length']; | |
这里需要把字符串split一下,用这个SpilitStrToTupleByItem类型 | |
拆分字符串也是`${A}${B}`,配合infer。 如果能拆分就继续拆分,否则返回结果 | |
拆分字符串 = Str extends `${infer RestStr}${StrItem}` ? 继续拆分: ResStr | |
整体实现就是这样,其实思路并不难,用js很容易写出来,难就难在ts没有那么多语法,只能用这些语法来实现一些东西,但是说简单也简单,因为只要你思路清楚了,就能一步步写出类型来。比如这个RepeatStr的实现过程。 | |
这道题主要还是考察模版字符串类型的,不管是构造字符串还是拆分字符串都是这个语法,还有就是只有数组能够判断长度,需要递归构造数组,这个可能比较耗费性能,但是一般情况下问题也不大。 | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment