当前位置: 首页 > Web前端 > JavaScript

TypeScript高(zhuāng)级(bī)用法Partial,Required,Readonly...

时间:2023-03-26 21:12:27 JavaScript

如何让一个类的所有属性都可选?例如,我有以下类型:typeUser={username:string;性别:'男性'|'女性';年龄:数字;生物:字符串;password:string;}User类型要求所有属性必须有值,所以:constuser:User={username:'awesomeuser',};不可行,会提示:type"{username:string;}"type"User"中缺少以下属性:gender,age,bio如何使其可行?只需要使用Partial:constuser:Partial={username:'awesomeuser'}Partial内置的内部类型就是让一个定义类型的所有属性都可选,具体实现如下:/***让所有属性inToptional*/typePartial={[PinkeyofT]?:T[P];};如何强制一个类型的所有属性?假设我们有这样一个类型定义:typeUser={username:string;年龄?:数字;性别?:'男性'|'女性'生物?:字符串;password?:string;}并从服务器后台获取一系列用户数据的结果:constusers:User[]=awaitapi.users.list();此时我们尝试访问用户的年龄进行比较,想要提取年龄>18的用户:constfilteredUsers=users.filter(user=>user.age>18);你的IDE此时是否提示你:对象可能是“undefined”。?为什么?因为我们定义了age本身是一个可选属性,当属性没有定义的时候,它的值是undefined,而在typescript中,undefined是不允许和number类型比较的,但是这个时候我们其实可以确定api.users.list接口返回给我,要么抛出错误,要么给我User类型的数据和年龄值,这样我就可以完全比较了,但是因为TypeScript不知道你加载的数据是什么我该怎么办用户或属性已经有值的特殊用户?任何必需的都可以。常量用户:必需的<用户>[]=[];或者让api.users.list()的返回类型为Required[]。如何实现自己需要:/***使T中的所有属性成为必需的*/typeRequired={[PinkeyofT]-?:T[P];};如何使一个类型的所有属性只读?假设我们现在正在写一个系统。当用户登录时,一个User对象将被所有组件共享,但只允许其他人读取它的值,其他人不允许修改它。但是,我们定义的User是整个系统共享的,具有编辑功能。的页面也在使用这种类型定义,需要能够修改用户数据,怎么办?只需使用Readonly:constuser={username:"awesomeuser",gender:"male",age:19,bio:"Aha,insight~",};constsharedUser=userasReadonly;sharedUser.username="新用户名";此时,IDE会告诉你不能赋值给“username”,因为它是一个只读属性。注意:TypeScript只进行静态类型验证,但不代表这些值不能修改。如果你真的想创建一个不能以编程方式修改的对象,我该如何解决呢?我想要一个类,它只包含另一个类或那个用户的部分属性定义。我想定义一个Login类型,专门用于登录的类型,但是我不想重写username和password的类型定义(虽然在这个例子中,重写一遍很简单,但是如果不完整,有一天你会遇到一个很复杂的类型定义?),怎么办?只需使用选择。输入User={用户名:字符串;性别?:“男性”|“女性”;年龄?:数字;生物?:字符串;password?:string;};typeLogin=Pick;constlogin:Login={username:"pantao",};如您所见,登录类型只需要用户名,密码是可选的。这不符合我们的要求。我应该怎么办?添加Required啊。输入User={用户名:字符串;性别?:“男性”|“女性”;年龄?:数字;生物?:字符串;password?:string;};typeLogin=Required>;constlogin:Login={用户名:"pantao",};这时候,你会被要求输入密码。如何实施Pickyourself?/***从T中选择一组键在联合K中的属性*/typePick={[PinK]:T[P];};如果你快速定义一个Type,属性是否具有相同的数据类型?假设我们现在正在开发一个购物中心系统。每个Store都有一个店长、一个仓库管理员和一个收银员。它们都与用户相关联。这时候可以定义Store的类型如下:typeUser={username:string;性别?:“男性”|“女性”;年龄?:数字;生物?:字符串;password?:string;};typeStore={name:string;位置:字符串;领导者:用户;仓库管理员:用户;收银员:用户;};当然你也可以这样定义:typeStore=Record<'leader'|'仓库管理员'|'收银员',User>&{name:string;location:string;}两种方式,哪一种更好,当然各有优缺点,但是假设我们遇到以下情况:typeUser={username:string;性别?:“男性”|“女性”;年龄?:数字;生物?:字符串;password?:string;};constusers:User=[{username:"awesomeuser",},{username:"baduser",},{username:"gooduser",},];为了方便访问,我想将users变量转换成一个对象,其属性名为users数组索引,值为users数组元素(即User类型)。如何定义这样的类型?你可以这样做:输入UserSet={[key:number]:用户};constuserSet:UserSet=用户。reduce((set,user,index)=>({...set,[index]:user}),{}asUserSet);您也可以这样做:键入UserSet=Record;如何实现记录自己?/***构造一个具有类型T的一组属性K的类型*/typeRecord={[PinK]:T;};