awesome-typescript icon indicating copy to clipboard operation
awesome-typescript copied to clipboard

「重学TS 2.0 」TS 练习题第九题

Open semlinker opened this issue 2 years ago • 26 comments

第九题

定义一个 JoinStrArray 工具类型,用于根据指定的 Separator 分隔符,对字符串数组类型进行拼接。具体的使用示例如下所示:

type JoinStrArray<Arr extends string[], Separator extends string, Result extends string = ""> = // 你的实现代码

// 测试用例
type Names = ["Sem", "Lolo", "Kaquko"]
type NamesComma = JoinStrArray<Names, ","> // "Sem,Lolo,Kaquko"
type NamesSpace = JoinStrArray<Names, " "> // "Sem Lolo Kaquko"
type NamesStars = JoinStrArray<Names, "⭐️"> // "Sem⭐️Lolo⭐️Kaquko"

请在下面评论你的答案

semlinker avatar Sep 14 '21 15:09 semlinker

type JoinStrArray<Arr extends string[], Separator extends string, Result extends string = ""> = 
    Arr extends [infer El,...infer Rest] ? 
            Rest extends string[] ?
            El extends string ?
            Result extends "" ?
            JoinStrArray<Rest, Separator,`${El}`> :
            JoinStrArray<Rest, Separator,`${Result}${Separator}${El}`> :
            `${Result}` :
            `${Result}` :
            `${Result}`

type Names = ["Sem", "Lolo", "Kaquko"]
type NamesComma = JoinStrArray<Names, ","> // "Sem,Lolo,Kaquko"
type NamesSpace = JoinStrArray<Names, " "> // "Sem Lolo Kaquko"
type NamesStars = JoinStrArray<Names, "⭐️"> // "Sem⭐️Lolo⭐️Kaquko"

semlinker avatar Sep 16 '21 01:09 semlinker

image

结果看起来没问题,但好像有报错

McDaddy avatar Sep 20 '21 06:09 McDaddy

type JoinStrArray<
  Arr extends string[],
  Separator extends string
> = Arr extends [infer A, ...infer B]
  ? `${A extends string ? A : ''}${B extends [string, ...string[]]
      ? `${Separator}${JoinStrArray<B, Separator>}`
      : ''}`
  : '';

ppbl avatar Sep 20 '21 22:09 ppbl

type JoinStrArray<Arr extends string[], Separator extends string> = Arr extends [infer El, ...infer Res]
    ? `${Arr[0]}${Res extends string[]
        ? Res[0] extends string
            ? `${Separator}${JoinStrArray<Res, Separator>}`
            : ""
        : ""}`
    : ""

// 测试用例
type Names = ["Sem", "Lolo", "Kaquko"]
type NamesComma = JoinStrArray<Names, ","> // "Sem,Lolo,Kaquko"
type NamesSpace = JoinStrArray<Names, " "> // "Sem Lolo Kaquko"
type NamesStars = JoinStrArray<Names, "⭐️"> // "Sem⭐️Lolo⭐️Kaquko"

Mrlgm avatar Sep 26 '21 16:09 Mrlgm

// 定义一个 JoinStrArray 工具类型,用于根据指定的 Separator 分隔符,对字符串数组类型进行拼接。具体的使用示例如下所示:

type JoinStrArray<Arr extends string[], Separator extends string, Result extends string = ""> = Arr extends [infer A, ...infer B]
  ? Result extends ""
    ? JoinStrArray<B, Separator, A>
    : JoinStrArray<B, Separator, `${Result}${Separator}${A}`>
  : Result;

// 测试用例
type Names = ["Sem", "Lolo", "Kaquko"]
type NamesComma = JoinStrArray<Names, ","> // "Sem,Lolo,Kaquko"
type NamesSpace = JoinStrArray<Names, " "> // "Sem Lolo Kaquko"
type NamesStars = JoinStrArray<Names, "⭐️"> // "Sem⭐️Lolo⭐️Kaquko"

这个题需要明白 类型映射的代码里可以用 js 里模板变量的用法。之后就是extends 配合 infer 从数组中提取类型出来。

zhaoxiongfei avatar Oct 01 '21 14:10 zhaoxiongfei

type ArrayShift<T extends string[]> = T extends [first: string, ...rest: infer R] ? R : [];

type JoinStrArray<Arr extends string[], Separator extends string, Result extends string = ""> = {
    2: Result,
    1: JoinStrArray<ArrayShift<Arr>, Separator, `${Result}${Arr[0]}`>
    0: JoinStrArray<ArrayShift<Arr>, Separator, `${Result}${Arr[0]}${Separator}`>
}[Arr extends [first: string, second: string, ...rest: string[]] ? 0 : Arr extends [] ? 2 : 1]

// 测试用例
type Names = ["Sem", "Lolo", "Kaquko"]
type NamesComma = JoinStrArray<Names, ","> // "Sem,Lolo,Kaquko"
type NamesSpace = JoinStrArray<Names, " "> // "Sem Lolo Kaquko"
type NamesStars = JoinStrArray<Names, "⭐️"> // "Sem⭐️Lolo⭐️Kaquko"

Cxdhz avatar Oct 14 '21 03:10 Cxdhz

type JoinStrArray<Arr extends string[],Separator extends string> = Arr extends [infer first, ...infer rest] ? ${first extends string ? first : ""}${rest extends [string, ...string[]] ? ${Separator}${JoinStrArray<rest, Separator>} : ""} : ""; // 你的实现代码

// 测试用例 type Names = ["Sem", "Lolo", "Kaquko"]; type NamesComma = JoinStrArray<Names, ",">; // "Sem,Lolo,Kaquko" type NamesSpace = JoinStrArray<Names, " ">; // "Sem Lolo Kaquko" type NamesStars = JoinStrArray<Names, "⭐️">; // "Sem⭐️Lolo⭐️Kaquko"

yanglinxiao avatar Nov 19 '21 06:11 yanglinxiao

type JoinStrArray<Arr, Separator extends string, Result extends string = ""> = ( Arr extends [infer L, ...infer R] ? L extends string ? JoinStrArray<R, Separator, ${Result}${Result extends '' ? '' : Separator}${L}> : never : Result )

// 测试用例 type Names = ["Sem", "Lolo", "Kaquko"] type NamesComma = JoinStrArray<Names, ","> // "Sem,Lolo,Kaquko" type NamesSpace = JoinStrArray<Names, " "> // "Sem Lolo Kaquko" type NamesStars = JoinStrArray<Names, "⭐️"> // "Sem⭐️Lolo⭐️Kaquko"

a572251465 avatar Dec 01 '21 08:12 a572251465

type JoinStrArray<Arr, Separator extends string, Result extends string = ""> = ( Arr extends [infer L, ...infer R] ? L extends string ? JoinStrArray<R, Separator, ${Result}${Result extends '' ? '' : Separator}${L}> : never : Result )

// 测试用例 type Names = ["Sem", "Lolo", "Kaquko"] type NamesComma = JoinStrArray<Names, ","> // "Sem,Lolo,Kaquko" type NamesSpace = JoinStrArray<Names, " "> // "Sem Lolo Kaquko" type NamesStars = JoinStrArray<Names, "⭐️"> // "Sem⭐️Lolo⭐️Kaquko"

a572251465 avatar Dec 01 '21 08:12 a572251465

type JoinStrArray<A extends string[], Separator extends string> = A extends [infer B, ...infer C] ? B extends string ? C extends [string, ...string[]] ? `${B}${Separator}${JoinStrArray<C, Separator>}` : B : '' : '';

liulise avatar Dec 07 '21 02:12 liulise

type JoinStrArray<A extends string[], Separator extends string> = 
    A extends [infer One, ...infer Others]
        ? One extends string
            ? Others extends string[]
                ? `${One}${Separator}${JoinStrArray<Others, Separator>}`
                : `${One}`
            : ''
        : A extends [infer OnlyOne]
            ? OnlyOne extends string
                ? `${OnlyOne}`
                : ''
            : '';

yang131323 avatar Jan 13 '22 07:01 yang131323

type JoinStrArray<Arr extends string[], Separator extends string, Result extends string = ""> = 
    Arr['length'] extends 0
        ? Result
        : Arr extends [infer First, ...infer Rest]
              ? First extends string
        ? Rest extends string[]
          ? Rest['length'] extends 0
            ? JoinStrArray<Rest, Separator, `${Result}${First}`>
            : JoinStrArray<Rest, Separator, `${Result}${First}${Separator}`>
          : ''
        : ''
      : ''

// 测试用例
type Names = ["Sem", "Lolo", "Kaquko"]
type NamesComma = JoinStrArray<Names, ","> // "Sem,Lolo,Kaquko"
type NamesSpace = JoinStrArray<Names, " "> // "Sem Lolo Kaquko"
type NamesStars = JoinStrArray<Names, "⭐️"> // "Sem⭐️Lolo⭐️Kaquko"

waleiwalei avatar Mar 11 '22 07:03 waleiwalei

type JoinStrArray<
  Arr extends string[],
  Separator extends string,
  Result extends string = ""
> = Arr extends [infer F, ...infer R]
  ? R extends string[]
    ? F extends string
      ? Result extends ""
        ? JoinStrArray<R, Separator, F>
        : JoinStrArray<R, Separator, `${Result}${Separator}${F}`>
      : Result
    : Result
  : Result;

zjxxxxxxxxx avatar Mar 23 '22 07:03 zjxxxxxxxxx

求大佬帮忙每步的意思解释一下吧,小弟着实是有点不懂了

obaqiang avatar Mar 24 '22 02:03 obaqiang

相当于是使用infer递归提取了rest参数, 然后再递归执行type

ChangerHe avatar May 27 '22 03:05 ChangerHe

求大佬帮忙每步的意思解释一下吧,小弟着实是有点不懂了

type JoinStrArray<Arr extends string[], Separator extends string, Result extends string = ""> =
    // (1)Arr是否约束于[]   真就执行(2)
    Arr extends [infer El, ...infer Rest] ?
    // (2)Rest是否约束于string[]  // 为真执行(3)
    Rest extends string[] ?
    // (3)El是否约束于string  // 为真执行(4)
    El extends string ?
    // (4)Result是否约束为""
    Result extends "" ?
    // (4)为真,递归调用JoinStrArray<Rest = Arr, Separator, `${El}` == Result>
    JoinStrArray<Rest, Separator, `${El}`> : // JoinStrArray<["Lolo","kaquko"], ",", "Sem"> 第一次递归调用 Result extends "" 为false
    JoinStrArray<Rest, Separator, `${Result}${Separator}${El}`> : // JoinStrArray<["kaquko"], "," ,"Sem, Lolo">
    `${Result}` : 
    `${Result}` : 
    `${Result}`

type Names = ["Sem", "Lolo", "Kaquko"]
type NamesComma = JoinStrArray<Names, ","> // "Sem,Lolo,Kaquko"
type NamesSpace = JoinStrArray<Names, " "> // "Sem Lolo Kaquko"
type NamesStars = JoinStrArray<Names, "⭐️"> // "Sem⭐️Lolo⭐️Kaquko"

YJCCreateAHistory avatar May 27 '22 11:05 YJCCreateAHistory

// 定义一个 JoinStrArray 工具类型,用于根据指定的 Separator 分隔符,对字符串数组类型进行拼接
type JoinStrArray<Arr extends string[], Separator extends string, Result extends string = ""> =
    // (1)Arr是否约束于[]
    Arr extends [infer El, ...infer Rest] ?
    // (2)Rest是否约束于string[] 
    Rest extends string[] ?
    // (3)El是否约束于string
    El extends string ?
    // (4)Result是否约束为""
    Result extends "" ?

    // (4)为真,递归调用JoinStrArray<Rest = Arr, Separator, `${El}` == Result>
    // JoinStrArray<["Lolo","kaquko"], ",", "Sem"> 第一次递归调用后Result extends "" 为false
    JoinStrArray<Rest, Separator, `${El}`> : 
    
    // JoinStrArray<["kaquko"], "," ,"Sem,Lolo"> 再次调用
    JoinStrArray<Rest, Separator, `${Result}${Separator}${El}`> :
    `${Result}` : 
    `${Result}` : 
    `${Result}`

type Names = ["Sem", "Lolo", "Kaquko"]
type NamesComma = JoinStrArray<Names, ","> // "Sem,Lolo,Kaquko"
type NamesSpace = JoinStrArray<Names, " "> // "Sem Lolo Kaquko"
type NamesStars = JoinStrArray<Names, "⭐️"> // "Sem⭐️Lolo⭐️Kaquko"``

YJCCreateAHistory avatar May 27 '22 11:05 YJCCreateAHistory

type RemoveFirstChar<T> = T extends ${string}${infer R}? R:T; type JoinStrArray<Arr extends string[], Separator extends string, Result extends string = ""> = Arr extends [infer F, ...infer Rest] ? JoinStrArray<Rest,Separator,${Result}${Separator}${F&string}>: RemoveFirstChar<Result>;// 你的实现代码

// 测试用例 type Names = ["Sem", "Lolo", "Kaquko"] type NamesComma = JoinStrArray<Names, ","> // "Sem,Lolo,Kaquko" type NamesSpace = JoinStrArray<Names, " "> // "Sem Lolo Kaquko" type NamesStars = JoinStrArray<Names, "⭐️"> // "Sem⭐️Lolo⭐️Kaquko"

edisonLzy avatar Jun 05 '22 07:06 edisonLzy

type JoinStrArray<Arr extends string[], Separator extends string, Result extends string = ""> = 
    Arr extends [infer First, ...infer Rest] ?
        First extends string ?
            Rest extends [string, ...string[]] ?
                JoinStrArray<Rest, Separator, `${Result}${First}${Separator}`>
                :
                `${Result}${First}`
            :
            `${Result}`
        :
        `${Result}`

LiuerQin avatar Jun 29 '22 06:06 LiuerQin

type JoinStrArray<Arr extends string[], Separator extends string, Result extends string = ""> = Arr extends [infer First, ...infer Rest] ? JoinStrArray<Rest, Separator, ${Result}${First & string}${Separator}> : Result

hezhisheng1930 avatar Aug 11 '22 09:08 hezhisheng1930

type JoinStrArray<Arr extends string[], Separator extends string, Result extends string = ""> = 
    Arr extends [infer El,...infer Rest] ? 
            Rest extends string[] ?
            El extends string ?
            Result extends "" ?
            JoinStrArray<Rest, Separator,`${El}`> :
            JoinStrArray<Rest, Separator,`${Result}${Separator}${El}`> :
            `${Result}` :
            `${Result}` :
            `${Result}`

type Names = ["Sem", "Lolo", "Kaquko"]
type NamesComma = JoinStrArray<Names, ","> // "Sem,Lolo,Kaquko"
type NamesSpace = JoinStrArray<Names, " "> // "Sem Lolo Kaquko"
type NamesStars = JoinStrArray<Names, "⭐️"> // "Sem⭐️Lolo⭐️Kaquko"

可以简化成

type JoinStrArray<Arr extends string[], Separator extends string, Result extends string = ""> = Arr extends [infer El extends string, ...infer Rest extends string[]]
  ? Result extends ""
    ? JoinStrArray<Rest, Separator, `${El}`>
    : JoinStrArray<Rest, Separator, `${Result}${Separator}${El}`>
  : `${Result}`

kuangxianfeng avatar Aug 22 '22 09:08 kuangxianfeng

type RemoveFirstItem<T extends string[]> = T extends [string, ... infer rest] ? rest : [];

type JoinStrArray<Arr extends string[], Separator extends string, Result extends string = ""> = Arr extends [] ? '' : Arr extends [string] ? ${Result}${Result extends "" ? "" : Separator}${Arr[0]} : ${Result}${JoinStrArray<RemoveFirstItem<Arr>, Separator, ${Result}${Result extends "" ? "" : Separator}${Arr[0]}>}

fasign avatar Oct 18 '22 09:10 fasign

没看懂,Result是什么?为啥定义了一个Result但是没传进去

hechuanhua avatar Jan 31 '23 09:01 hechuanhua

type JoinStrArray<Arr extends string[], Separator extends string, Result extends string = ""> = 
    Arr extends [infer El,...infer Rest] ? //一层判断,若true则执行第二层判断。否则执行结果1
            Rest extends string[] ?  //二层判断,若true则执行第三层判断。否则执行结果2
            El extends string ?  //三层判断,若true则执行第四层判断。否则执行结果3
            Result extends "" ?  //四层判断,若true则执行结果5。否则执行结果4
            JoinStrArray<Rest, Separator,`${El}`> :  //结果5
            JoinStrArray<Rest, Separator,`${Result}${Separator}${El}`> : //结果4
            `${Result}` :  //结果3
            `${Result}` :  //结果2
            `${Result}`   //结果1

//上面的判断把每组三元表达式画个括号层次就清楚了
//一二三层判断是为了判断递归中是否还有非空数组传进来,有就继续拼接,没有则返回上回拼接结果
//结果5为首次递归,传递数组第一个元素作为拼接结果
//结果4为非首次递归,将当前数组第一个元素和上次拼接结果进行拼接并传递给下回

type Names = ["Sem", "Lolo", "Kaquko"]
type NamesComma = JoinStrArray<Names, ","> // "Sem,Lolo,Kaquko"
type NamesSpace = JoinStrArray<Names, " "> // "Sem Lolo Kaquko"
type NamesStars = JoinStrArray<Names, "⭐️"> // "Sem⭐️Lolo⭐️Kaquko"

shiyicyh avatar Aug 23 '23 01:08 shiyicyh

type JoinStrArray<Arr extends string[], Separator extends string, Result extends string = ""> = 
    Arr extends [infer El,...infer Rest]
    ? Rest extends string[]
      ? El extends string
        ? Result extends ""
          ? JoinStrArray<Rest, Separator,`${El}`>
          : JoinStrArray<Rest, Separator,`${Result}${Separator}${El}`>
        :`${Result}`
      : `${Result}`
    : `${Result}`

这个答案我看了半天,调了一下缩进终于看懂了。论缩进的重要性......

SweeperDuan avatar Dec 11 '23 09:12 SweeperDuan

//没看懂那个Result是干嘛的
type JoinStrArray<
	Arr extends string[],
	Separator extends string,
> = Arr extends [infer First extends string, ...infer Rest extends string[]]
	? `${First}${Separator}${JoinStrArray<Rest, Separator>}`
	: "";

JustWantToHappy avatar Feb 12 '24 12:02 JustWantToHappy