BFE-TS TypeScript类型体操练习 41- 50
大约 3 分钟
BFE-TS TypeScript类型体操练习 41- 50
题目来自TypeScript题目 | BFE.dev - 前端刷题,准备前端面试拿到心仪的Offer,总共60题,带你完爆类型体操!
常用工具类型 41-44
实现 LengthOfString<T>
实现
LengthOfString<T>
用以返回字符串长度。type A = LengthOfString<'BFE.dev'> // 7 type B = LengthOfString<''> // 0
答案:
转为元组后直接访问泛型的.length属性
type StringToTuple<T extends string> = T extends `${infer L}${infer R}` ? [L, ...StringToTuple<R>] : []; type LengthOfString<T extends string> = StringToTuple<T>['length'];
辅助数组统计长度
type LengthOfString< T extends string, U extends 0[] = [] > = T extends `${infer A}${infer B}` ? LengthOfString<B, [0, ...U]> : U["length"];
实现 LengthOfTuple<T>
实现
LengthOfTuple<T>
返回tuple type的长度。type A = LengthOfTuple<['B', 'F', 'E']> // 3 type B = LengthOfTuple<[]> // 0
答案:
直接访问泛型的.length属性
type LengthOfTuple<T extends any[]> = T["length"]
实现 StringToTuple<T>
实现
StringToTuple<T>
将字符串拆散为tuple,类似String.prototype.split('')
效果type A = StringToTuple<'BFE.dev'> // ['B', 'F', 'E', '.', 'd', 'e','v'] type B = StringToTuple<''> // []
答案:
type StringToTuple<T extends string> = T extends `${infer A}${infer B}` ? [A, ...StringToTuple<B>] : []
实现 LastItem<T>
FirstItem<T>
类似,请实现LastItem<T>
用以返回tuple的最后一个typetype A = LastItem<[string, number, boolean]> // boolean type B = LastItem<['B', 'F', 'E']> // 'E' type C = LastItem<[]> // never
答案:
type LastItem<T extends any[]> = T extends [...infer Firsts, infer Last] ? Last : never
相类似的
type LastItem<T extends any[]> = T extends [...any[], infer M] ? M : never;
有挑战性的题目 45-50
实现UndefinedToNull<T>
根据题 176. undefined to null,实现
UndefinedToNull<T>
,将对象、元组or传入泛型的undefined转置为nulltype A = UndefinedToNull<string> // string type B = UndefinedToNull<undefined> // null type C = UndefinedToNull<[undefined, null]> // [null, null] type D = UndefinedToNull<{ a: undefined, b: [1, undefined] }> // {a: null, b: [1, null]}
答案:
type UndefinedToNull<T> = T extends Record<string, any> ? { [K in keyof T]: UndefinedToNull<T[K]> } : (T extends [infer A, ...infer B] ? [A, ...UndefinedToNull<B>] : T extends undefined ? null : T)
实现MapStringUnionToObjectUnion<U>
将字符串联合映射到联合对象类型,如下所示。
type A = MapStringUnionToObjectUnion<'1'> // { // value: '1' // } type B = MapStringUnionToObjectUnion<'1' | '2'> // { // value: '1' // } | // { // value: '2 // }
答案:
type MapStringUnionToObjectUnion<U extends string> = { [k in U]: { value: k } }[U]
实现Diff<A, B>
找不同,即A,B中只存在一边的keys
type A = DiffKeys<{a: 1, b: 2}, {b: 1, c: 2}> // 'a' | 'c'
答案:
type DiffKeys< A extends Record<string, any>, B extends Record<string, any> > = Exclude<keyof A, keyof B> | Exclude<keyof B, keyof A>
实现ObjectPaths<O>
ObjectPaths<O>
,能够返回属性的所有有效路径type Obj = { a: { b: { c: 1, d: 2 }, e: 1 }, f: 3 } type A = ObjectPaths<Obj> // 'a.b.c' | 'a.b.d' | 'a.e' | 'f'
答案:
type ObjectPaths<O extends Record<string, any>> = { [K in keyof O]: K extends string ? O[K] extends Record<string, any> ? `${K}.${ObjectPaths<O[K]>}` : `${K}` : never }[keyof O];
实现StringToNumber<S>
将字符串转换为数字,假设字符串都是有效的非负整数
type A = StringToNumber<'12'> // 123
答案:
type StringToNumber<S extends string, T extends any[] = []> = `${T['length']}` extends S ? T['length'] : StringToNumber<S, [...T, any]>
实现Abs<N>
获取数字的绝对值,假设数字都是整数
答案:
type StringToNumber<S extends string, T extends any[] = []> = `${T['length']}` extends S ? T['length'] : StringToNumber<S, [...T, any]> type Abs<N extends number, T extends any[] = []> = `${N}` extends `-${infer A}` ? Abs<StringToNumber<A>> : StringToNumber<`${N}`>