2024-09-30 06:10:04
本文章并不是一篇干货满满的技术文章,主要是来谈谈自己目前对TypeScript这门语言的掌握程度的一种吐槽以及阶段性总结。
我并不知道大家是如何学习TypeScript,反正感觉到目前为止感觉自己TypeScript现在也只能处于一种初级入门水平。用用接口,定义定义函数,简单的使用下泛型。最近呢也因为自己也在开发一个后台管理系统模板,使用的是Vue3+TS嘛,在学习Vue3的小伙伴们可以参考下这个学习项目并且给点意见谢谢咯。VueAdminPro,但是有时候自己对于一些规范性的东西比较较真,常常会因为一个类型的定义纠结好久。
那个时候就感觉自己的TS水平特别拉跨,并且没有一点感觉它带给我的便捷,反而感觉约束了我降低了自己的开发效率。
然后其实很早就知道TS类型体操这玩意了,但是只是了解到类型体操和刷Leetcode题是一样的,所以之前也就并没有去尝试。就是感觉自己菜了,把到时候每做一道题挫败感就来了。
收获??但是在昨天五一的时候,去逛GitHub的时候又看看了type-challenges发现这个仓库更新的频率很频繁并且看了看Issues大家提交目前都5k+了。所以我也觉得自己改尝试尝试了。
从昨天晚上到今天早上,已经把easy类目的题目都做了一遍并且做了一些笔记。现在自己也添加了一个仓库FlingYP-Type-Challenges用来记录自己做题的记录和笔记。希望愿意看我的给个Star吧,嘻嘻~~
下面就是我做这些简单题做的一些笔记,如果有哪里写的有问题,希望指正。
FlingYP-Type-Challengesextends关键字在TS中,extends关键字代表着从一个类型扩展出另外一个新类型,这个新类型是原来这个类型的子类型(是扩展的意思,并非继承的意思)
typeSome=AextendsB?C:D条件类型
keyof关键字typeTestKeyof=keyofT
简单的说:keyof关键字将对象T类型的属性的Key全部收集起来组成为一个Union联合类型赋给类型TestKeyof
//?通过?keyof?T?如果T类型是一个数组?则组成的会是一个数组索引组成的联合类型interface?KeyOfPerson?{??name:?string;??age:?number;??sex:?number;}//?PersonKeys?类型是一个:?"name"?|?"age"?|?"sex"?的联合类型type?PersonKeys?=?keyof?KeyOfPerson;在TS中声明类型时,如何遍历对象类型?参考00004-easy-pick
type?MyPick<T,?K?extends?keyof?T>?=?{??//?遍历的写法:?[P?in?K]??[P?in?K]:?T[P];};Readonly的使用将类型所有的属性都设置为可读属性
interface?Person?{??name:?string;??age:?number;??sex:?number;}type?ReadonlyPerson?=?Readonly<Person>;//?type?ReadonlyPerson?=?{//???readonly?name:?string;//???readonly?age:?number;//???readonly?sex:?number;//?}asconst断言的类型通过asconst断言的变量就会变成一个readonlyType
//?readonly?["tesla",?"model?3",?"model?X",?"model?Y"]const?tuple?=?["tesla",?"model?3",?"model?X",?"model?Y"]?as?const;typeof关键字获取到变量的类型
在TS中声明类型时,如何遍历数组类型?参考00011-easy-tuple-to-object
type?TupleToObject<T?extends?readonly?any[]>?=?{??//?遍历写法:[key?in?T[number]]??[key?in?T[number]]:?key;};在TS中如果类型是一个数组,获取数组类型长度的方式?参考00018-easy-tuple-length
type?Length<T?extends?readonly?any[]>?=?T["length"];Exclude工具类型Exclude<UnionType,ExcludedMembers>从UnionType排除ExcludedMembers所定义的类型从而返回一个新的类型
type?T2?=?Exclude<string?|?number?|?(()?=>?void),?Function>;?=>?type?T2?=?string?|?number联合类型的遍历参考00043-easy-exclude。联合类型的遍历:TextendsU?Type1:Type2(想象成联合类型的每一个类型都会进一遍这个三元表达式,因此来进行判断)
type?MyExclude<T,?U>?=?T?extends?U???never?:?T;Awaited<T>工具类型Awaited<T>是TS4.5新添加的内置工具类型。可以帮助我们返回Promise对象里的类型。https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-5.html
关于00189-easy-awaited第二种方法的理解关键在于Infer关键字的使用,Infer只能用于条件类型extendsInfer关键字
/**?*?假如我们有一个?Promise?对象,这个?Promise?对象会返回一个类型。在?TS?中,我们用?Promise?中的?T?来描述这个?Promise?返回的类型。请你实现一个类型,可以获取这个类型。?*?比如:Promise<ExampleType>,请你返回?ExampleType?类型。?*///?第一种答案//?type?MyAwaited<T?extends?Promise<unknown>>?=?Awaited<T>;//?第二种答案type?MyAwaited<T?extends?Promise<unknown>>?=?T?extends?Promise<infer?X>????X?extends?Promise<unknown>??????MyAwaited<X>????:?X??:?never;//?1.?Awaited<>?是?TS?4.5?新添加的内置工具类型。?可以帮助我们返回Promise对象里的类型//?https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-5.html//?2.?Infer?关键字的理解使用/**?*?对于第二种答案的理解:要理解Infer关键字的作用?和?递归?*??1.?我们传给?MyAwaited<T>?的?T?泛型限制了?必须是?Promise?的类型,这样就解决了??type?error?=?MyAwaited<number>;?的爆红问题?*??2.?在根据?T?限制了必须是?Promise?类型,所以这段代码?T?extends?Promise<infer?X>???Type1?:?Type2??是一定会走?Type1的,因此?Type2?写什么类型都无所谓?*??3.?进入到?Type1?后,先要理解下?Infer?关键字?在?条件类型?extends?的作用,?Infer?是推断的意思,意思就是?假设?Promise<T>?里的泛型的类型?是?X?类型?*??4.?然后问??X?类型?它是不是也是?Promise?类型?如果是?则进入?MyAwaited<X>?进行递归操作?*??5.?如果不是Promise类型,则返回这个?X?类型?*/关于00898-easy-includes答案的理解/**?*?在类型系统里实现?JavaScript?的?Array.includes?方法,这个类型接受两个参数,?*?返回的类型要么是?true?要么是?false。?*/import?{?Equal?}?from?"@type-challenges/utils";//?type?Includes<T?extends?readonly?any[],?U>?=?any;??//(没做出来)//?答案:type?Includes<T?extends?readonly?any[],?U>?=?T?extends?[??infer?First,??...infer?Rest]????Equal<U,?First>?extends?true??????true????:?Includes<Rest,?U>??:?false;//?Infer?关键字的理解和使用//?@type-challenges/utils?类型工具的?Equal?类型工具/**?*?这道题没有做做出来,关键是没有想过?infer?可以这么写,也没有想到?使用了?Equal,所以对数组类型的遍历?没有思路?*?1.?和?00189-easy-awaited?的第二种解发思路一样,使用?Infer?和?递归?*?2.?首先传入的?泛型?T?在经过类型约束:?T?extends?readonly?any[]??后,一定不会走到?false的?*?3.?T?extends?[infer?First,...infer?Rest]?在这里假设了?T泛型,中的第一个元素的类型是?First?可以看做数学里的(未知数X),其他的类型是?Rest?可以看做数学里的(未知数Y)?*?4.?然后判断?第一个元素类型First?和?第二个泛型参数的类型是否一致,这里就使用到了Equal:?Equal<U,?First>?extends?true。?如果是则直接返回true,就没必要进行后面的递归操作了?*?5.?如果第一个元素类型参数不一致,就进行递归操作。?其实就是在拿泛型U和泛型T的第一个元素的类型做比较。?*/总结??在刷完类型体操的简单题后,瞬间感觉自己之前学的是假的TS吧,怎么有这么多知识点是自己没有用过的甚至没有见过。这是多么痛的领悟。总结就是一句话:想要玩转TypeScript,就来跳转类型体操。谢谢总结完毕??