Skip to content

Instantly share code, notes, and snippets.

@QuarkGluonPlasma
Created April 19, 2021 16:37
Show Gist options
  • Save QuarkGluonPlasma/6093135dd073220afb67eda714d17113 to your computer and use it in GitHub Desktop.
Save QuarkGluonPlasma/6093135dd073220afb67eda714d17113 to your computer and use it in GitHub Desktop.
重复字符串的TS类型
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