0


ArkTS的进阶语法-1(泛型,工具类型,空安全)

ArkTS的进阶语法

(本来是打算不更新的,一觉醒来发现又多了7个粉丝,这下必须得更新了😁)

(今天更新的是泛型,工具类型,空安全)

1. 泛型🎈

泛型在保证类型安全(不丢失类型信息)的同时,可以让函数等与多种不同的类型一起工作,灵活可复用

通俗一点就是:类型是可变的!

1.泛型函数

顾名思义就是,泛型和函数结合到一起使用

Type 是泛型参数的名字,类似于之前的形参,

  • 可以自行定义,有意义即可
  • 首字母大写
  • 参见泛型参数名 T、Type> > // 函数定义> function identity<Type>(arg: Type): Type {> return arg;> }> ​> // 在使用的时候传入具体的类型,函数就可以正常工作啦~> identity<string>('123')> identity<number>(123)> identity<boolean>(false)> identity<string[]>(['1', '2', '3'])> > 结合 编译器 的 类型推断 功能,在使用函数的时候还可以进行简写,比如下面的写法,和上面的是一样的。虽然大部分时候可以推断出类型,但是如果碰到 编译器 无法推断类型时,就需要显式传入类型参数,这在更复杂的示例中可能会发生。
  1. identity('123')
  2. identity(123)
  3. identity(false)
  4. identity(['1', '2', '3'])

使用泛型变量

类型变量可以用在任意支持的位置,实现更为复杂的功能

  1. //将类型变量 Type,作为数组项的类型即可
  2. function identity<Type>(arr: Type[]): number {
  3. return arr.length
  4. }
2.使用泛型约束

如果开发中不希望任意的类型都可以传递给 类型参数 ,就可以通过泛型约束来完成

核心步骤:

  1. 定义用来约束的 接口(interface)
  2. 类型参数通过 extends 即可实现约束> > interface 接口{> 属性:类型> }> function 函数<Type extends 接口>(){}> ​> // 后续使用函数时,传入的类型必须要有 接口中的属性> ------试一试> interface ILengthwise {> length: number> }> ​> function identity<Type extends ILengthwise>(arr: Type) {> console.log(arr.length.toString())> }> ​> // 使用的时候 只要有 length 属性即可> identity([1, 2, 3, 4]) // 数组有 length 属性 正常运行> identity('1234') // 字符串也有 length 属性 正常运行> ​> // identity(124) // 数值没有 length 属性 报错> ​> class Cloth implements ILengthwise {> length: number = 10> }> ​> class Trousers {> length: number = 110> }> ​> identity(new Cloth()) // Cloth 有 length 属性 正常运行> identity(new Trousers()) // Trousers 有 length 属性 正常运行> ​> >
3.多个泛型参数

日常开发的时候,如果有需要可以添加多个 类型变量,只需要定义并使用 多个类型变量即可

  1. function funcA<T, T2>(param1: T, param2: T2) {
  2. console.log('参数 1', param1)
  3. console.log('参数 2', param2)
  4. }
  5. funcA<string, number>('张三', 18)
  6. funcA<string[], boolean[]>(['张三','李四'], [false])
4.泛型接口

定义接口时结合泛型,那么这个接口就是 泛型接口

  1. interface 接口<Type>{
  2. // 内部使用Type
  3. }
  4. interface IdFunc<Type> {
  5. id: (value: Type) => Type
  6. ids: () => Type[]
  7. }
  8. let obj: IdFunc<number> = {
  9. id(value) { return value },
  10. ids() { return [1, 3, 5] }
  11. }
5.泛型类

和泛型接口类似,如果定义类的时候结合泛型,那么这个类就是 泛型类

  1. class 类名<Type>{
  2. // 内部可以使用 Type
  3. }
  4. -----试一试
  5. // 定义
  6. class Person <T> {
  7. id: T
  8. constructor(id: T) {
  9. this.id = id
  10. }
  11. getId(): T {
  12. return this.id
  13. }
  14. }
  15. // 使用
  16. let p = new Person<number>(10)

2.工具类型🎈

ArkTS提供了4 中工具类型,来帮组我们简化编码

4 种工具类型中,熟练掌握 Partial 即可,可以简化编码

1.partial<Type>

(partial:部分)

基于传入的Type类型构造一个[新类型],将Type的所有属性设置为可选。

(泛型约束太复杂了这个完全可以替代他)

  1. type 新类型 = Partial<接口>
  2. type 新类型 = Partial<类>
  3. // 后续使用新类型即可
  4. interface Person {
  5. name: string
  6. age: number
  7. friends: string[]
  8. }
  9. type ParPerson = Partial<Person>
  10. // 因为都是可选的,可以设置为空对象
  11. let p: ParPerson = {}
2.Required<Type>

基于传入的Type类型构造一个【新类型】,将 Type 的所有属性设置为必填

  1. type 新类型 = Required<接口>
  2. type 新类型 = Required<类>
  3. // 后续使用新类型即可
  4. class Person {
  5. name?: string
  6. age?: number
  7. friends?: string[]
  8. }
  9. type RequiredPerson = Required<Person>
  10. // 都是必须得属性,必须设置值
  11. let p: Required<Person> = {
  12. name: 'jack',
  13. age: 10,
  14. friends: []
  15. }
3.Readonly<Type>

基于 Type构造一个【新类型】,并将Type 的所有属性设置为readonly

  1. type 新类型 = Readonly<接口>
  2. type 新类型 = Readonly<类>
  3. // 后续使用新类型即可
  4. class Person {
  5. name: string = ''
  6. age: number = 0
  7. }
  8. type ReadonlyIPerson = Readonly<Person>
  9. const p: ReadonlyIPerson = {
  10. name: 'jack',
  11. age: 10
  12. }
  13. p.name = 'rose' // 报错 属性全部变成只读
4.Record<Keys,Type>

构造一个对象类型,其属性键为Keys,属性值为Type。该实用程序可用于将一种类型的属性映射到另一种类型。

  1. class CatInfo {
  2. age: number = 0
  3. breed: string = ''
  4. }
  5. // 联合类型
  6. type CatName = "miffy" | "boris" | "mordred";
  7. // 通过Record 构建新的对象类型
  8. // 属性名:必须是CatName 中的值
  9. // 属性值:必须是CatInfo 类型
  10. type Ctype = Record<CatName, CatInfo>
  11. const cats: Ctype = {
  12. 'miffy': { age: 5, breed: "Maine Coon" },
  13. 'boris': { age: 5, breed: "Maine Coon" },
  14. 'mordred': { age: 16, breed: "British Shorthair" },
  15. };

3.空安全🎈

默认情况下,ArkTS中的所有类型都是不可为空的。如果要设置为空,需要进行特殊的处理,并且在获取 可能为空的值的时候也需要特殊处理

1.联合类型设置为空
  1. let x: number = null; // 编译时错误
  2. let y: string = null; // 编译时错误
  3. let z: number[] = null; // 编译时错误
  4. 通过联合类型指定为空即可,使用时可能需要判断是否为空
  5. // 通过联合类型设置为空
  6. let x: number | null = null;
  7. x = 1; // ok
  8. x = null; // ok
  9. // 取值的时候,根据需求可能需要考虑 屏蔽掉空值的情况
  10. if (x != null) { /* do something */ }
2.非空断言运算符

后缀运算符! 可用于断言其操作数为非空。

应用于空值时,运算符将抛出错误。否则,值的类型将从T | null更改为T:

  1. let x: number | null = 1;
  2. let y: number
  3. y = x + 1; // 编译时错误:无法对可空值作加法
  4. y = x! + 1; // 通过非空断言,告诉编译器 x不为 null
3.空值合并运算符

空值合并二元运算符?? 用于检查左侧表达式的求值是否等于null。如果是,则表达式的结果为右侧表达式;否则,结果为左侧表达式。

换句话说,a ?? b等价于三元运算符a != null ? a : b。

在以下示例中,getNick方法如果设置了昵称,则返回昵称;否则,返回空字符串:

  1. class Person {
  2. name: string | null = null
  3. getName(): string {
  4. // return this.name === null ? '' : this.name
  5. // 等同于 如果 name不为空 就返回 name 反之返回 ''
  6. return this.name ?? ''
  7. }
  8. }
4.可选链

在访问对象属性时,如果该属性是undefined或者null,可选链运算符会返回undefined。

(可选链?当前面的对象不为空或undefined才调用属性或方法)

  1. class Dog {
  2. bark() {
  3. console.log('啊呜~')
  4. }
  5. }
  6. class Person {
  7. name?: string
  8. dog?: Dog
  9. constructor(name: string, dog?: Dog) {
  10. this.name = name
  11. this.dog = dog
  12. }
  13. }
  14. const p: Person = new Person('jack')
  15. // p.dog.bark()// 报错 dog 可能为空
  16. // 逻辑判断
  17. if (p.dog) {
  18. p.dog.bark()
  19. }
  20. // 当 dog不为null 或 undefined 时 再调用 bark 并且不会报错
  21. p.dog?.bark()

---------------------------------------感觉写的不错的话就点点关注吧😘❤❤❤----------------------------------------------

标签: 华为 harmonyos 前端

本文转载自: https://blog.csdn.net/weixin_67448099/article/details/143659361
版权归原作者 我爱学习_zwj 所有, 如有侵权,请联系我们删除。

“ArkTS的进阶语法-1(泛型,工具类型,空安全)”的评论:

还没有评论