來(lái)做一個(gè)好玩的猜數(shù)字游戲吧。

看一下游戲規(guī)則。
通常由兩個(gè)人玩,一方出數(shù)字,一方猜。出數(shù)字的人要想好一個(gè)沒(méi)有重復(fù)數(shù)字的4個(gè)數(shù),不能讓猜的人知道。猜的人就可以開(kāi)始猜。每猜一個(gè)數(shù)字,出數(shù)者就要根據(jù)這個(gè)數(shù)字給出幾A幾B,其中A前面的數(shù)字表示位置正確的數(shù)的個(gè)數(shù),而B(niǎo)前的數(shù)字表示數(shù)字正確而位置不對(duì)的數(shù)的個(gè)數(shù)。
如正確答案為 5234,而猜的人猜 5346,則是 1A2B,其中有一個(gè)5的位置對(duì)了,記為1A,而3和4這兩個(gè)數(shù)字對(duì)了,而位置沒(méi)對(duì),因此記為 2B,合起來(lái)就是 1A2B。
js 寫(xiě)猜數(shù)字好寫(xiě),就是2個(gè)循環(huán),那ts中怎么實(shí)現(xiàn)呢
extentds
extends 可以判斷出 A 類(lèi)型 是否是 B 類(lèi)型的子類(lèi),對(duì)于 字符串,數(shù)字類(lèi)型就相當(dāng)于判斷值相等
解構(gòu) infer
在`${infer A}${infer B}` 中 infer 相當(dāng)于將結(jié)構(gòu)的字符串值賦給一個(gè)類(lèi)型 A 和 B ,遞歸一下就有了獲取每一位的字符串的能力
范型遞歸
可以用 extends 作為終止條件,遞歸的調(diào)用類(lèi)型,在遞歸中加入?yún)?shù)的傳遞,最后可以輸出一個(gè)元祖類(lèi)型當(dāng)作結(jié)果
type Fn<Arr extends 1[] = []> = Arr['length'] extends 5
? Fn<[...Arr, 1]>
: '結(jié)束'
ts猜數(shù)字的實(shí)現(xiàn)
// +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'>