type-challenge刷题
内容接前文
easy
type mypick<t, k extends keyof t> = {[k in k]: t[k]}; type myreadonly<t> = {readonly [k in keyof t]: t[k]}; type tupletoobject<t extends readonly (string|number|symbol)[]> = {[k in t[number]]: k}; type first<t extends any[]> = t extends [infer head, ...unknown[]] ? head : never; type length<t extends readonly unknown[]> = t["length"]; // 题目要求readonly数组 type if<c extends boolean, t, f> = c extends true ? t : f; type concat<t extends unknown[], u extends unknown[]> = [...t, ...u]; type push<t extends unknown[], u> = [...t, u]; type unshift<t extends unknown[], u> = [u, ...t]; type myparameters<t extends (...args: any[]) => any> = t extends (...args: infer u) => any ? u : never;
exclude
原题地址
type myexclude<t, u> = t extends u ? never : t;
这里有个遗漏的知识点...分配条件类型
当type
参数联合类型时,内部其实是作循环处理的。以exclude
为例,分配条件类型的实际处理如下
myexclude<'a'|'b'|'c', 'a'|'b'> = ('a' extends 'a'|'b' ? never : 'a') | ('b' extends 'a'|'b' ? never : 'b') | ('c' extends 'a'|'b' ? never : 'c')
await
原题地址
type promiselike<t = unknown> = {then: (cb: (arg: t)=>unknown) => unknown}; type myawaited<t extends promiselike> = t extends promiselike<infer u> ? (u extends promiselike ? myawaited<u> : u) : never;
需要实现await
,即const result = await promiseval
的await
。
此处实现方式类似promise a+协议中的resolvepromise
部分,之所以以自定义的promiselike
作为promise
的判断条件,是因为在resolvepromise
中,判断一个对象是否是promise,是以typeof promise.then === "function"
作为判断条件,这保证了不同pollyfill实现的promise函数之间可以相互进行链式调用,且满足promiselike
的对象都能用async...await
语法。
include
原题地址
type eq<x, y> = (<t>() => t extends x ? 1 : 2) extends (<t>() => t extends y ? 1 : 2) ? true : false type includes<t extends readonly any[], u> = t extends [infer h, ...infer rest] ? (eq<h, u> extends false ? includes<rest, u>: true) : false;
include
主体部分还好,最麻烦的是equal
部分,一开始写的equal
如下
type eq<x, y> = x extends y ? (y extends x ? true : false) : false; // 这个是错的,测试用例如下 type check = eq<boolean, true> // boolean
这里忽略了boolean
其实是个复合类型,根据前面分配条件类型提到的,作为参数传递时会进行遍历
type check = eq<boolean, true> // boolean // ⬇️ // boolean -> true|false // ====> eq<true, true>|eq<false, true> -> true|false -> boolean
直接翻看了'@type-challenges/utils'
的库,发现它是利用function
的定义绕过对象的extends
判断。。这一点比较具有启发性
type eq<x, y> = // 这里没有直接进行x和y的比较,那样会触发分配条件类型 // 因此借助范型的变量t作为桥梁进行比较 (<t>() => t extends x ? 1 : 2) extends (<t>() => t extends y ? 1 : 2) ? true : false
习惯了常规编程语言的语法后,很容易忽略【分配条件类型】这条规则,可以借用中间变量的思想,间接绕过直接的extends
判定
以上就是type-challenge刷题(easy部分)示例详解的详细内容,更多关于type-challenge刷题的资料请关注代码网其它相关文章!
发表评论