当前位置: 代码网 > it编程>编程语言>Javascript > type-challenge刷题(easy部分)示例详解

type-challenge刷题(easy部分)示例详解

2024年05月15日 Javascript 我要评论
type-challenge刷题内容接前文type-challenge挑战地址easytype mypick<t, k extends keyof t> = {[k in k]: t[k]

type-challenge刷题

内容接前文

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 promisevalawait

此处实现方式类似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刷题的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com