TypeScript 类型体操姿势合集记录 type-challenges/README.zh-CN.md at main · type-challenges/type-challenges (github.com)
298 - Length of String
计算字符串的长度,类似于 String#length
,在 Github 上查看 。
1 2 3 4 5 type LengthOfString < S extends string , arr extends unknown [] = [] > = S extends `${infer first} ${infer rest} ` ? LengthOfString <rest,[...arr,first]> : arr['length' ]
459 - Flatten
在这个挑战中,你需要写一个接受数组的类型,并且返回扁平化的数组类型。在 Github 上查看 ,例如:
1 type flatten = Flatten <[1 , 2 , [3 , 4 ], [[[5 ]]]]>
1 2 3 4 5 6 7 8 9 10 11 type FlattenArrayVal <S extends any ,T extends unknown []=[]> = S extends unknown [] ? S extends [infer first,...infer rest] ? FlattenArrayVal <rest, first extends unknown [] ? FlattenArrayVal <first,T> : [...T,first]> : T : S type Flatten <S extends unknown [],T extends unknown []=[]> = S extends [infer first,...infer rest] ? Flatten <FlattenArrayVal <rest>, [...T,FlattenArrayVal <first>]> : T
解释:类型 flattenArrayVal
的作用是处理数组中的每一项,非数组类型直接返回原样,数组类型返回扁平化后的数组,给Flatten
使用。
527 - Append to object
实现一个为接口添加一个新字段的类型。该类型接收三个参数,返回带有新字段的接口类型。在 Github 上查看 ,例如:
1 2 type Test = { id : '1' }type Result = AppendToObject <Test , 'value' , 4 >
1 2 3 type AppendToObject <T extends Object , U extends string , V> = { [K in keyof T | U]: K extends keyof T ? T[K] : V }
529 - Absolute
实现一个接收string,number或bigInt类型参数的Absolute
类型,返回一个正数字符串。在 Github 上查看 ,例如:
1 2 type Test = -100 ;type Result = Absolute <Test >;
1 2 type Absolute <T extends number | string | bigint > = `${T} ` extends `-${infer V} ` ? V : `${T} `
501 - String to Union
实现一个将接收到的String参数转换为一个字母Union的类型。在Github 上查看 ,例如:
1 2 type Test = '123' ;type Result = StringToUnion <Test >;
1 2 3 4 5 type StringToUnion <T extends string > = T extends "" ? never : T extends `${infer first} ${infer rest} ` ? first | StringToUnion <rest> : T
599 - Merge
将两个类型合并成一个类型,第二个类型的键会覆盖第一个类型的键。在 Github 上查看 ,例如:
1 2 3 4 5 6 7 8 9 10 11 type foo = { name : string ; age : string ; } type coo = { age : number ; sex : string } type Result = Merge <foo,coo>;
1 2 3 type Merge <F extends Object , S extends Object > = { [K in keyof F | keyof S]: K extends keyof S ? S[K] : K extends keyof F ? F[K] : never }
612 - KebabCase
FooBarBaz->
foo-bar-baz,在Github上查看 。
1 2 3 4 5 6 7 8 type FirstLowcase <T extends string > = T extends `${infer F} ${infer R} ` ? F extends Lowercase <F> ? T : `${Lowercase<F>} ${R} ` : T type KebabCase <S extends string > = S extends `${infer F} ${infer R} ` ? R extends FirstLowcase <R> ? `${FirstLowcase<F>} ${KebabCase<R>} ` : `${FirstLowcase<F>} -${KebabCase<FirstLowcase<R>>} ` : S
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 type KebabMap = { A : "a" B : "b" C : "c" D : "d" E : "e" F : "f" G : "g" H : "h" I : "i" J : "j" K : "k" L : "l" M : "m" N : "n" O : "o" P : "p" Q : "q" R : "r" S : "s" T : "t" U : "u" V : "v" W : "w" X : "x" Y : "y" Z : "z" } type KebabCase < S extends string , U extends string = "" > = S extends `${infer Target} ${infer R} ` ? Target extends keyof KebabMap ? U extends "" ? KebabCase <R, `${U} ${KebabMap[Target]} ` > : KebabCase <R, `${U} -${KebabMap[Target]} ` > : KebabCase <R, `${U} ${Target} ` > : U
645 - Diff
获取两个接口类型中的差值属性。在 Github 上查看 ,例如:
1 2 3 4 5 6 7 8 9 10 11 type Foo = { a : string ; b : number ; } type Bar = { a : string ; c : boolean } type Result1 = Diff <Foo ,Bar > type Result2 = Diff <Bar ,Foo >
第一种:
1 2 3 type Diff <O extends object , O1 extends object > = { [K in (keyof Omit <O & O1 , keyof (O | O1 )>)]: K extends keyof O ? O[K] : K extends keyof O1 ? O1 [K]:neve
第二种:
1 2 3 4 type Diff <O extends object , O1 extends object > = { [K in keyof Omit <O1 , keyof O> | keyof Omit <O, keyof O1 >]: K extends keyof O ? O[K] : K extends keyof O1 ? O1 [K]:never }
949 AnyOf
在类型系统中实现类似于 Python 中 any
函数。类型接收一个数组,如果数组中任一个元素为真,则返回 true
,否则返回 fasle
。如果数组为空,返回 false
。在Github上查看 ,例如:
1 2 type Sample1 = AnyOf <[1 , '' , false , [], {}]> type Sample2 = AnyOf <[0 , '' , false , [], {}]>
第一种:
1 2 type FalsyVal <V> = V extends [] | Record <string , never > | '' | 0 | false ? false : true type AnyOf <T extends readonly any []> = true extends FalsyVal <T[number ]> ? true : false
第二种:
1 2 type FalsyVal = [] | Record <string , never > | '' | 0 | false type AnyOf <T extends readonly any []> = T extends [infer Head , ...infer Tail ] ? Head extends FalsyVal ? AnyOf <Tail > : true : false
1042 IsNever
Implement a type IsNever, which takes input type T
. If the type of resolves to never
, return true
, otherwise false
. 在Github上查看 。For example:
1 2 3 4 5 type A = IsNever <never > type B = IsNever <undefined > type C = IsNever <null > type D = IsNever <[]> type E = IsNever <number >
第一种:
1 2 3 type IsNever <T> = [T] extends [never ] ? true : false
第二种:
1 type IsNever <T> = {[key : string ]: T} extends {[key : string ]: never } ? true : false ;
原文链接: https://xiaozhouguo.github.io/2022/05/30/typescript/type-challanges/
版权声明: 转载请注明出处.