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刷题的资料请关注代码网其它相关文章!
发表评论