【ts类型体操】猜数字

来做一个好玩的猜数字游戏吧。


image.png

看一下游戏规则。

通常由两个人玩,一方出数字,一方猜。出数字的人要想好一个没有重复数字的4个数,不能让猜的人知道。猜的人就可以开始猜。每猜一个数字,出数者就要根据这个数字给出几A几B,其中A前面的数字表示位置正确的数的个数,而B前的数字表示数字正确而位置不对的数的个数。
如正确答案为 5234,而猜的人猜 5346,则是 1A2B,其中有一个5的位置对了,记为1A,而3和4这两个数字对了,而位置没对,因此记为 2B,合起来就是 1A2B。

js 写猜数字好写,就是2个循环,那ts中怎么实现呢

extentds

extends 可以判断出 A 类型 是否是 B 类型的子类,对于 字符串,数字类型就相当于判断值相等

解构 infer

`${infer A}${infer B}` 中 infer 相当于将结构的字符串值赋给一个类型 A 和 B ,递归一下就有了获取每一位的字符串的能力

范型递归

可以用 extends 作为终止条件,递归的调用类型,在递归中加入参数的传递,最后可以输出一个元祖类型当作结果

   type Fn<Arr extends 1[] = []> = Arr['length'] extends 5
    ? Fn<[...Arr, 1]>
    : '结束'

ts猜数字的实现

// +1
type Aplus1<n extends number, arr extends 1[] = []> = n extends arr['length']
    ? [...arr, 1]['length']
    : Aplus1<n, [...arr, 1]>

type Each<char extends string, S extends string, charIndex extends number, index extends number = 0, A extends 0 | 1 = 0, B extends 0 | 1 = 1> =
    S extends `${infer P}${infer Q}`
    ? char extends P
    ? charIndex extends index  // 不算
    ? [1, 0]
    // @ts-ignore
    : Each<char, Q, charIndex, Aplus1<index>, 0, 1>
    // @ts-ignore
    : Each<char, Q, charIndex, Aplus1<index>, A, B>
    : [A, B]

type Main<S1 extends string, S2 extends string, index extends number = 0, A extends 1[] = [], B extends 1[] = []> =
    S1 extends `${infer P}${infer Q}`
    ? Each<P, S2, index> extends [infer CA, infer CB]
    ? Main<Q, S2, Aplus1<index>, CA extends 0 ? A : [...A, 1], CB extends 0 ? B : [...B, 1]>
    : never
    : [`A:${A['length']}`, `B:${B['length']}`]

type Questen1<T extends string> = Main<T, 'zengpengshabi'>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。