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

目录

ArkTS的进阶语法

[1. 泛型🎈](#1. 泛型🎈)

1.泛型函数

2.使用泛型约束

3.多个泛型参数

4.泛型接口

5.泛型类

2.工具类型🎈

1.partial

3.空安全🎈

1.联合类型设置为空

2.非空断言运算符

3.空值合并运算符

4.可选链

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'])

    结合 编译器 的 类型推断 功能,在使用函数的时候还可以进行简写,比如下面的写法,和上面的是一样的。

    虽然大部分时候可以推断出类型,但是如果碰到 编译器 无法推断类型时,就需要显式传入类型参数,这在更复杂的示例中可能会发生。

复制代码
identity('123')
identity(123)
identity(false)
identity(['1', '2', '3'])

使用泛型变量

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

复制代码
//将类型变量 Type,作为数组项的类型即可
function identity<Type>(arr: Type[]): number {
  return arr.length
}
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.多个泛型参数

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

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

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

复制代码
interface 接口<Type>{
  // 内部使用Type
}
interface IdFunc<Type> {
  id: (value: Type) => Type
  ids: () => Type[]
}
​
let obj: IdFunc<number> = {
  id(value) { return value },
  ids() { return [1, 3, 5] }
}
5.泛型类

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

复制代码
class 类名<Type>{
  // 内部可以使用 Type
}
-----试一试
// 定义
class Person <T> {
  id: T
​
  constructor(id: T) {
    this.id = id
  }
​
  getId(): T {
    return this.id
  }
}
​
// 使用
let p = new Person<number>(10)
​
​

2.工具类型🎈

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

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

1.partial<Type>

(partial:部分)

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

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

复制代码
type 新类型 = Partial<接口>
type 新类型 = Partial<类>
​
// 后续使用新类型即可
interface Person {
  name: string 
  age: number 
  friends: string[]
}
​
type ParPerson = Partial<Person>
​
// 因为都是可选的,可以设置为空对象
let p: ParPerson = {}
​
2.Required<Type>

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

复制代码
type 新类型 = Required<接口>
type 新类型 = Required<类>
​
// 后续使用新类型即可
class Person {
  name?: string
  age?: number
  friends?: string[]
}
​
type RequiredPerson = Required<Person>
​
// 都是必须得属性,必须设置值
let p: Required<Person> = {
  name: 'jack',
  age: 10,
  friends: []
}
​
3.Readonly<Type>

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

复制代码
type 新类型 = Readonly<接口>
type 新类型 = Readonly<类>
​
// 后续使用新类型即可
class Person {
  name: string = ''
  age: number = 0
}
​
type ReadonlyIPerson = Readonly<Person>
​
const p: ReadonlyIPerson = {
  name: 'jack',
  age: 10
}
​
p.name = 'rose' // 报错 属性全部变成只读
​
4.Record<Keys,Type>

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

复制代码
class CatInfo {
  age: number = 0
  breed: string = ''
}
​
// 联合类型
type CatName = "miffy" | "boris" | "mordred";
​
// 通过Record 构建新的对象类型
// 属性名:必须是CatName 中的值
// 属性值:必须是CatInfo 类型
type Ctype = Record<CatName, CatInfo>
​
const cats: Ctype = {
  'miffy': { age: 5, breed: "Maine Coon" },
  'boris': { age: 5, breed: "Maine Coon" },
  'mordred': { age: 16, breed: "British Shorthair" },
};
​

3.空安全🎈

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

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

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

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

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

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

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

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

复制代码
class Person {
  name: string | null = null
​
  getName(): string {
    // return this.name === null ? '' : this.name
    // 等同于 如果 name不为空 就返回 name 反之返回 ''
    return this.name ?? ''
  }
}
​
4.可选链

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

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

复制代码
class Dog {
  bark() {
    console.log('啊呜~')
  }
}
​
class Person {
  name?: string
  dog?: Dog
​
  constructor(name: string, dog?: Dog) {
    this.name = name
    this.dog = dog
  }
}
​
const p: Person = new Person('jack')
​
// p.dog.bark()// 报错 dog 可能为空
​
// 逻辑判断
if (p.dog) {
  p.dog.bark()
}
​
// 当 dog不为null 或 undefined 时 再调用 bark 并且不会报错
p.dog?.bark()

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

相关推荐
前端拾光者6 分钟前
前端数据可视化思路及实现案例
前端·数据库·信息可视化
诗歌难吟46418 分钟前
初识ArkUI
harmonyos
沉默璇年22 分钟前
react中Fragment的使用场景
前端·react.js·前端框架
SameX32 分钟前
HarmonyOS Next 设备安全特性深度剖析学习
harmonyos
不熬夜的臭宝35 分钟前
每天10个vue面试题(九)
javascript·vue.js·ecmascript
前端熊猫1 小时前
transform学习
前端·学习·html
sun lover1 小时前
electron快速上手
javascript·electron
GISer_Jing1 小时前
React渲染流程与更新diff算法
前端·javascript·react.js
郑祎亦1 小时前
JavaWeb开发:HTML 页面与接口对接
前端·后端·java-ee·html
Au_ust1 小时前
css:感觉稍微高级一点的布局
前端·css