🐱 个人主页:不叫猫先生
🙋♂️ 作者简介:2022年度博客之星前端领域TOP 2,前端领域优质作者、阿里云专家博主,专注于前端各领域技术,共同学习共同进步,一起加油呀!
💫优质专栏:vue3从入门到精通、TypeScript从入门到实践
📢 资料领取:前端进阶资料以及文中源码可以找我免费领取
🔥 前端学习交流:博主建立了一个前端交流群,汇集了各路大神,一起交流学习,期待你的加入!(文末有我wx或者私信)。

目录
TypeScript 2.8版本引入了条件类型(Conditional Types),TS条件类型可以进行类型选择,具体用法可以使用三元运算符实现,JS中的三元运算符用法一样,通过判断得到最终结果,TS条件类型最终得到的是数据类型。
条件类型允许根据一个或多个条件对类型进行推断,并且还能在在类型级别上进行复杂的逻辑运算和类型操作。
当T类型可以赋值给U类型时,则返回X类型,否则返回Y类型。
T extends U ? X : Y
列举例子如下:
其中TypeName为条件类型,根据T的具体类型返回不同类型的字符串,也就是字面量类型。
type TypeName<T> =
T extends string ? "string" :
T extends number ? "number" :
T extends boolean ? "boolean" :
T extends undefined ? "undefined" :
T extends Function ? "function" :
"object";
type A = TypeName<'1'> //"string"
type B = TypeName<1> //"number"
type C = TypeName<true> //"blolean"
type D = TypeName<undefined> //"undefined"
type E = TypeName<()=>void> //"function"
type F = TypeName<{}> //"object "
当被检查类型T为联合类型时:
type G = TypeName<'1'| 1 | true> // "string" | "number" | "boolean"
type H = TypeName<()=>void | {}> // "function" | "object"
在条件类型中,如果被检查的类型是一个 “裸” 类型参数,即没有被数组、元组或 Promise 等包装过,则该条件类型被称为分布式条件类型。当分布式条件类型中被检查类型为联合类型,则在运算过程中分解多个分支 。
type typeName<T> = T extends number ? "X" : "Y" ;
type H = typeName<string | number> // "X" | "Y"
//上面typeName在计算类型时,会分解为如下:
type H = string extends number ? "X" : "Y" | number extends number ? "X" : "Y"
= "X" | "Y"
当T被数组、元组、Promise等包裹时,则运算过程中不会分解成多个分支,则该条件类型为非分布式条件类型。
type WrappedTuple<T> = [T] extends [boolean] ? "X" : "Y";
type WrappedArray<T> = T[] extends boolean[] ? "X" : "Y";
type WrappedPromise<T> = Promise<T> extends Promise<boolean> ? "X" : "Y";
type G = WrappedTuple<string | boolean>; // "Y"
type K = WrappedArray<string | boolean>; // "Y"
type L = WrappedPromise<string | boolean>; // "Y"
解析:
//由于计算数据时不会分解成多个分支
// [T] extends [boolean]
//WrappedTuple<string | boolean> 中 string | boolean 不是 boolean 类型,也不是其他原始类型
//T[] extends boolean[]
//WrappedArray<string | boolean> 中 string | boolean 不是 boolean 类型,也不是其他原始类型
//Promise<T> extends Promise<boolean>
//WrappedPromise<string | boolean> 中 string | boolean 不是 boolean 类型,也不是其他原始类型
在联合类型T中删除联合类型U中的成员,T类型中的剩余成员则组成新的类型。下面例子中,如果类型T为类型U的子类型,则返回never,否则返回类型T
type Diff<T, U> = T extends U ? never : T;
type A = Diff<"a" | "b" | "c", "a" | "c" | "d">; // "b"
在联合类型T中过滤出联合类型U中的成员,过滤出来的成员则组成新的类型。下面例子中,如果类型T为类型U的子类型,则返回类型T,否则返回never
type Filter<T, U> = T extends U ? T : never;
type B = Filter<"a" | "b" | "c", "a" | "c" | "d"> ; // "a" | "c"
条件类型除了可以使用extends,也可以使用infer关键字。infer 关键字可以用于从一个类型中提取另一个类型。
type FunctionReturnType<T> = T extends (...args: any[]) => infer R ? R : never;
定义了FunctionReturnType条件类型,它会检查类型T是否为函数类型,如果是则通过infer获取函数的返回值类型R,否则返回never类型。具体案例如下:
type FRT1 = FunctionReturnType<() => number> //number
type FRT2 = FunctionReturnType<(x: string, y: number) => string[]> //string
type FRT3 = FunctionReturnType<() => void>//void
type FRT4 = FunctionReturnType<() => {}>//{}
type FRT5 = FunctionReturnType<1>//never
keyof主要是获取某个对象/类型的属性名来构成新类型。我们可以使用条件类型和 keyof 关键字来获取对象的属性。具体案例如下:
type PropertyType<T, K extends keyof T> = K extends keyof T ? T[K] : never;
上面代码定义了类型为PropertyType<T, K extends keyof T>,通过检查K是否是T的一个属性名,如果是则返回该属性类型,否则返回never。
type Obj = { a: string; b: number };
type A = PropertyType<Obj, "a">; // string
type B = PropertyType<Obj, "c">; // never
映射类型是泛型类型的一种,可用于把原有的对象类型映射成新的对象类型。我们可以使用条件类型和 keyof关键字来实现Partial类型,Partial类型是TS工具类之一。具体案例如下:
type Partial<T> = {
[K in keyof T]? : T[K]
}
定义类型Partial<T>,遍历T中所有属性,然后通过?将所有属性变成可选属性。
type obj = {a:string,b:number}
type R = Partial<obj>//{a?:string,b?:number}
注意:Partial是TS的工具类,所以声明Partial是会报错的,可以换个标识符名称。

《深入理解设计模式》
活动规则:评论区进行优质评论
抽奖规则:根据 优质评论 以及 优质评论点赞量 抽取 三人
活动时间:即日起至2023年4月11日 12:00
温馨提示:参与活动者提前参加博主wx(文末附有),以避免错过中奖通知。

本书系统介绍了23种设计模式,根据具体的实例形象化、具体化地进行了代码的编写和详细讲解,让那些本来对设计模式不太了解、一知半解、只有概念的读者,彻底了解和掌握常用的设计模式使用场景及使用方式,并掌握每个设计模式的UML结构和描绘方式。本书共23章,包括认识设计模式、单例模式、工厂模式、建造者模式、原型模式、适配器模式、装饰器模式、外观模式、桥接模式、组合模式、享元模式、代理模式、策略模式、命令模式、状态模式、模板方法模式、备忘录模式、中介者模式、观察者模式、迭代器模式、责任链模式、访问者模式、解释器模式。通过以上的知识,让你从模式小白直接升级为模式大神!本书所需源代码,均可通过本书配套下载链接获得。
我可以得到Infinity和NaNn=9.0/0#=>Infinityn.class#=>Floatm=0/0.0#=>NaNm.class#=>Float但是当我想直接访问Infinity或NaN时:Infinity#=>uninitializedconstantInfinity(NameError)NaN#=>uninitializedconstantNaN(NameError)什么是Infinity和NaN?它们是对象、关键字还是其他东西? 最佳答案 您看到打印为Infinity和NaN的只是Float类的两个特殊实例的字符串
我不确定传递给方法的对象的类型是否正确。我可能会将一个字符串传递给一个只能处理整数的函数。某种运行时保证怎么样?我看不到比以下更好的选择:defsomeFixNumMangler(input)raise"wrongtype:integerrequired"unlessinput.class==FixNumother_stuffend有更好的选择吗? 最佳答案 使用Kernel#Integer在使用之前转换输入的方法。当无法以任何合理的方式将输入转换为整数时,它将引发ArgumentError。defmy_method(number)
我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden
我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin
我有一个只接受一个参数的方法:defmy_method(number)end如果使用number调用方法,我该如何引发错误??通常,我如何定义方法参数的条件?比如我想在调用的时候报错:my_method(1) 最佳答案 您可以添加guard在函数的开头,如果参数无效则引发异常。例如:defmy_method(number)failArgumentError,"Inputshouldbegreaterthanorequalto2"ifnumbereputse.messageend#=>Inputshouldbegreaterthano
有时我需要处理键/值数据。我不喜欢使用数组,因为它们在大小上没有限制(很容易不小心添加超过2个项目,而且您最终需要稍后验证大小)。此外,0和1的索引变成了魔数(MagicNumber),并且在传达含义方面做得很差(“当我说0时,我的意思是head...”)。散列也不合适,因为可能会不小心添加额外的条目。我写了下面的类来解决这个问题:classPairattr_accessor:head,:taildefinitialize(h,t)@head,@tail=h,tendend它工作得很好并且解决了问题,但我很想知道:Ruby标准库是否已经带有这样一个类? 最佳
我正在尝试解析一个CSV文件并使用SQL命令自动为其创建一个表。CSV中的第一行给出了列标题。但我需要推断每个列的类型。Ruby中是否有任何函数可以找到每个字段中内容的类型。例如,CSV行:"12012","Test","1233.22","12:21:22","10/10/2009"应该产生像这样的类型['integer','string','float','time','date']谢谢! 最佳答案 require'time'defto_something(str)if(num=Integer(str)rescueFloat(s
我正在玩HTML5视频并且在ERB中有以下片段:mp4视频从在我的开发环境中运行的服务器很好地流式传输到chrome。然而firefox显示带有海报图像的视频播放器,但带有一个大X。问题似乎是mongrel不确定ogv扩展的mime类型,并且只返回text/plain,如curl所示:$curl-Ihttp://0.0.0.0:3000/pr6.ogvHTTP/1.1200OKConnection:closeDate:Mon,19Apr201012:33:50GMTLast-Modified:Sun,18Apr201012:46:07GMTContent-Type:text/plain
我的Gallery模型中有以下查询:media_items.includes(:photo,:video).rank(:position_in_gallery)我的图库模型有_许多媒体项,每个都有一个照片或视频关联。到目前为止,一切正常。它返回所有media_items包括它们的photo或video关联,由media_item的position_in_gallery属性排序。但是我现在需要将此查询返回的照片限制为仅具有is_processing属性的照片,即nil。是否可以进行相同的查询,但条件是返回的照片等同于:.where(photo:'photo.is_processingIS
除了可访问性标准不鼓励使用这一事实指向当前页面的链接,我应该怎么做重构以下View代码?#navigation%ul.tabbed-ifcurrent_page?(new_profile_path)%li{:class=>"current_page_item"}=link_tot("new_profile"),new_profile_path-else%li=link_tot("new_profile"),new_profile_path-ifcurrent_page?(profiles_path)%li{:class=>"current_page_item"}=link_tot("p