TS 进阶练习

TS内容进阶,紧随上篇文章  https://www.cnblogs.com/jickma/p/18025212  TS 学习随笔

学习内容源自 https://blog.csdn.net/weixin_44441196/article/details/123570019?spm=1001.2014.3001.5501 

练习1    将接口中属性修改为只读

 1 /**
 2  * 将接口中属性修改为只读 
 3  */
 4 interface Person {
 5   name: string,
 6   age: number,
 7   readonly phone: number
 8 }
 9 /**
10  * 完全看不懂什么用法,
11  * 按照我的理解就是创建了一个新的 接口,这个接口叫 ReadOnlyPerson 可以用这个接口创建新的对象
12  * 接口中的属性是 Person 中的属性,通过 in keyof(猜测类似于js 对象循环的方法)重新定义的属性
13  * name: string, 可以理解为 key为name ,value为string  
14  * [P in keyof Person]为 key,Person[P]为value
15  * 而 readonly 为修饰符,表示只读
16  * type 应该为一个关键字,表示创建一个新接口
17  */
18 type ReadOnlyPerson = {
19   readonly [P in keyof Person]: Person[P]
20 }
21 let personOne: Person = {
22   name: '张三',
23   age: 24,
24   phone: 1234567890
25 }
26 personOne.name = '王五'
27 let personTwo: ReadOnlyPerson = {
28   name: '李四',
29   age: 26,
30   phone: 190000
31 }
32 // personTwo.name = '赵云' // 报错 无法为“name”赋值,因为它是只读属性。
33 /**
34  * 在代码书写完成之后就会直接报错,并无法运行,
35  * 在js中对象是没有只读这样的属性的,
36  * 编译成功之后的js仅为两个名叫 personOne personTwo 的两个对象
37  * 以及对name值得修改
38  */
39 // console.log(personOne, 'personOne'); // { name: '王五', age: 24, phone: 1234567890 } personOne
40 // console.log(personTwo, 'personTwo'); // { name: '李四', age: 26, phone: 190000 } personTwo

练习2   将某个 interface 里的索引全部转为联合类型

 1 /**
 2  * 将某个 interface 里的索引全部转为联合类型
 3  */
 4 /**
 5  * 联合类型 就是用| 将多个类型组合在一起,
 6  * 在定义变量类型时候有遇到
 7  */
 8 // 这便是联合类型
 9 // let strOrNum: number | string = '张飞'
10 // strOrNum = 123456
11 interface Animal {
12   name: string,
13   age: number,
14   readonly phone: number
15 }
16 type UnionTypes = keyof Animal
17 /**
18  * 试了一些方法,但是始终无法输出正确得联合类型数据 别人得贴子输出是这样的
19  * 'name' | 'age' | 'gender'
20  * UnionTypes 是无法直接输出得 直接输出报错 “UnionTypes”仅表示类型,但在此处却作为值使用。
21  */
22 let typeAAA: UnionTypes = "name" // 网上说这个地方会显示 UnionTypes 得可选值,我的没有出现
23 // console.log(typeAAA,'typeAAA'); // name 

练习3  将两个interface组成一个新的interface

 1 /**
 2  * 将两个interface组成一个新的interface
 3  */
 4 interface type1 {
 5   name: string
 6   readonly age: number
 7 }
 8 interface type2 {
 9   adress: string
10 }
11 type type3 = type1 & type2
12 /**
13  * type1 中没有adress这个属性
14  * 语法错误。
15  * 对象字面量只能指定已知属性,并且“adress”不在类型“type1”中。
16  */
17 // let typeAll1: type1 = {
18 //   name: '景天',
19 //   age: 24,
20 //   adress: '永安当' // 对象字面量只能指定已知属性,并且“adress”不在类型“type1”中。
21 // }
22 let typeAll: type3 = {
23   name: '景天',
24   age: 24,
25   adress: '永安当'
26 }
27 // console.log(typeAll, 'typeAll'); // { name: '景天', age: 24, adress: '永安当' }
28 interface type4 {
29   // name: number
30   adress: string
31   phone: number
32 }
33 type type5 = type1 & type2 & type4
34 /**
35  * 由此可以推断出,这个地方可以无限制合并
36  * 如果属性有相同得 并且type值也相同,没有问题,并不会显示两个 adress
37  * 如果type不同 就会报错 不能将类型“string”分配给类型“never”。
38  * 如 name 上面是 string类型,下边是 number类型,无论我在赋值时候写什么都是显示这句话
39  */
40 let typeAllKey: type5 = {
41   name: '茂山',
42   age: 23,
43   adress: '永安当',
44   phone: 132456
45 }
46 // console.log(typeAllKey, 'typeAllKey'); // { name: '茂山', age: 24, adress: '永安当', phone: 132456 }

 练习4  利用 pick 从一个interface中选择索引生成新的interface  利用 Omit 从一个interface中排除部分择索引生成新的interface

 1 /**
 2  * 利用 pick 从一个interface中选择索引生成新的interface
 3  * 利用 Omit 从一个interface中排除部分择索引生成新的interface
 4  * pick Omit 可以理解为返回某些数据和不返回某些数据
 5  * pick 在已经定义的对象中选取一些 pick<T,keys> T表示选择谁的属性 keys表示选择哪几个属性(传入属性名,只能是第一个 类型变量中存在的属性)
 6  * Omit 在已经定义的对象中删除一些 Omit<T,keys> 
 7  * 除了这两个还有 Exclude(排除/不包括) Extract (提取/包括) 这两个用法与 pick Omit 不同,暂时未测试
 8  */
 9 interface car {
10   name: string
11   width: number
12   height: number
13   weight: number | string
14   speed: number | string
15 }
16 // 现在有一个新的车,这个车只有长宽,
17 type onlyHasWH = Pick<car, 'width' | 'height'>
18 let onlyHasWHObj: onlyHasWH = {
19   // name: '凯迪拉克', // 语法错误 对象字面量只能指定已知属性,并且“name”不在类型“onlyHasWH”中。
20   width: 120,
21   height: 490
22 }
23 // console.log(onlyHasWHObj); // { width: 120, height: 490 }
24 // 现在又有一个新车,这个车除了长宽其余得都有
25 type onlyNoWH = Omit<car, 'width' | 'height'>
26 let onlyNoWHObj: onlyNoWH = {
27   name: '凯迪拉克',
28   // width: 120, // 语法错误 对象字面量只能指定已知属性,并且“width”不在类型“onlyNoWH”中。
29   // height: 490
30   weight: '120kg',
31   speed: '200km/h'
32 }
33 // console.log(onlyNoWHObj); // { name: '凯迪拉克', weight: '120kg', speed: '200km/h' }

练习5  利用InstanceType从一个类里面获取interface

 1 /**
 2  * 利用InstanceType从一个类里面获取interface
 3  * InstanceType 接受一个类类型作为参数,并返回该类的实例类型。 
 4  */
 5 class person {
 6   name: string
 7   age: number
 8   readonly sex: string = ''
 9   constructor(name: string, age: number) {
10     this.name = name
11     this.age = age
12   }
13 }
14 // InstanceType 就是把一个类中得属性拿出来了,然后可以单独用作一个新的对象 对于只读属性,是可以直接修改得
15 type newPerson = InstanceType<typeof person>
16 let a: newPerson = {
17   name: '李淳风',
18   age: 89,
19   sex: ''
20 }

练习6  利用Parameters从函数的参数中推导出类型  利用ReturnType从函数的返回值中推导出类型

 1 /**
 2  * 利用Parameters从函数的参数中推导出类型
 3  * 利用ReturnType从函数的返回值中推导出类型
 4  * 这两个是从函数里面获取参数类型与返回值得类型
 5  * 在函数中入参类型确定之后,返回值类型也就能确定了
 6  */
 7 function foo1(v: string, b: number) {
 8   return v + b
 9 }
10 let foo2 = (v: string, b: number) => {
11   return v + b
12 }
13 // 函数这两种写法是一样得,没有差别都可以使用
14 type parame1 = Parameters<typeof foo1>
15 // 得出来的是一个数组 parame1 [v: string, b: number] 如果参数再多,那数组长度增加
16 let a1: parame1 = ['1', 1] // 如果写别类型的就会报语法错误,比如说布尔值
17 type parame2 = ReturnType<typeof foo1>
18 // 最终结果得到的是一个 字符串
19 let a2:parame2 = '111' // 如果写别的类型就会报语法错误

 

posted @ 2024-02-27 17:00  马文庆i  阅读(17)  评论(0编辑  收藏  举报