泛型简述

泛型:指在定义时不会设置具体类型,在使用时再进行类型的定义(通俗一点就是:类型是可变的!)

1、泛型 — 函数

function 函数名<Type>(形参:Type):Type{
}

// 定义泛型参数 Type,后续可以使用类型的位置均可以使用比如:

// 1. 参数类型
function 函数名<Type>(形参:Type){
}

// 2. 返回值类型
function 函数名<Type>(形参:Type):Type{
}

泛型函数的注意点(数组相关)

2、泛型约束extends

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

//泛型约束——>不希望得到任意类型,需要对类型约束
//语法:  定义接口   function 函数名 <泛型 extends 接口 > (){}
interface YueShu{
  name:string
}
function fun <T extends YueShu>(a:T){
  return a
}
// 注意:如果传递或返回的数据是对象   类型推断都推断不出来 需要手动指定类型,不然报错
let res=fun<YueShu>({name:'泛型约束'})
console.log(``,res)

3、泛型—接口

4、多个泛型


5、泛型 — 类

泛型类:定义类的时候结合泛型,那么这个类就是 泛型类

语法:class 类<泛型>{
  使用泛型
}

last:泛型总结

//--------------------泛型---------------------------
// ------------泛型函数
function fun1<T, T2>(a: number[], b: T2): number {
  let res = 0
  for (let item of a) {
    res += item
  }
  return res
}
fun1<number[], string>([1, 2, 3], '泛型函数')

// -----------泛型约束
interface fun2demo {
  name: string
  age: number
  hobby: string
}
function fun2<T extends fun2demo>(a: T) {
  console.log(`泛型约束`, a)
}
fun2<fun2demo>({ name: '泛型约束', age: 1, hobby: '传递或返回的数据是对象 需要手动添加类型' })

// -----------泛型接口
interface jieKou<T1, T2> {
  jieKou1: T1
  jieKou2: T2
  fun: (a: T2) => string
}
let obj: jieKou<string, number> = {
  jieKou1: '泛型接口1',
  jieKou2: 2,
  fun: (a: number) => {
    return a + '泛型接口(对象)'
  }
}
console.log(`泛型接口`, obj.jieKou1)
console.log(`泛型接口`, obj.jieKou2)
console.log(`泛型接口`, obj.fun)

// -----------泛型类
class DemoLei<T1, T2, T3> {
  name: T1
  age: T2

  constructor(name: T1, age: T2) {
    this.name = name
    this.age = age
  }

  fun(a: T3): T3 {
    return a
  }
}
//实例化:T1=string, T2=number, T3=boolean
//使用(两种方式都可以)
let lei1 = new DemoLei<string, number, boolean>('泛型类', 2) //实例化类——的时候传递类型
let lei2: DemoLei<string, number, boolean> = new DemoLei('泛型类', 2) //实例化对象——的时候传递类型
console.log(`lei1`, lei1.fun(false))
console.log(`lei2`, lei2.fun(true))

//----------类和泛型结合
class FanLei<T, T2> {
  demo1: T
  demo2: T2

  constructor(demo1: T, demo2: T2) {
    this.demo1 = demo1
    this.demo2 = demo2
  }

  demoFun() {
    return this.demo1
  }
}
const fanLei: FanLei<string, string[]> = new FanLei('类和泛型结合', ['类和泛型', '结合'])
fanLei.demoFun()

// ---------接口和类结合(构造函数初始化时更加方便)
interface JkLei {
  demo1: string
  demo2: number
}
class JkLeiDemo {
  demo1: string
  demo2: number

  constructor(value: JkLei) {
    this.demo1 = value.demo1
    this.demo2 = value.demo2
  }
}
const jkLeiDemo: JkLeiDemo = new JkLeiDemo({ demo1: '接口和类结合', demo2: 2 }) //传值的时候要传递对象
console.log(`接口和类结合`,jkLeiDemo.demo1)

// 类的属性限制implements-(类必须要有接口中的属性数据)
interface JkDemo<T> {
  name: string
  age: number
  fun1: (d:T) => T
}
class LeiDemo<T> implements JkDemo<T> {
  name: string
  age: number
  fun1: (b:T) => T
  hobby: string
  constructor(value: JkDemo<T>, hobby: string) {
    this.name = value.name
    this.age = value.age
    this.fun1 = value.fun1
    this.hobby = hobby
  }
  fun() {
    console.log(`名称: ${this.name}, 年龄: ${this.age}, 爱好: ${this.hobby}`)
  }
}
const Obj: LeiDemo<string> = new LeiDemo({
  name: 'implements',
  age: 1,
  fun1: (c:string) => {
  return c
  }
}, '爱好')
console.log(`Obj`, Obj.fun1('11'))// 11


@Entry
@Component
struct MY_FANXING {
  build() {
    TextTimer()
      .height('100%')
      .width('100%')
  }
}

工具类型

partial<Type>必填变可选

// 工具类
//Partial  Partial<Type> 作用:将必选属性变成可选属性
interface Demo{
  name:string
  age:number
}
 // Partial<Dog>产生新类型(Required_首字母要大写)

// 使用新类型(两种方式)
type IType = Partial<Demo>
let my1:IType={}

let my2:Partial<Demo>={}//因为是可选属性,空对象也不报错

@Entry
@Component
struct GongJuleiPartial {
  @State data :Partial<Demo>={}//使用场景
  build() {
   Column(){}
    .height('100%')
    .width('100%')
  }
}

Required<Type>可选变必填

// 工具类
//Required  Required<Type> 作用:可选属性变为必填
interface Demo{
  name?:string
  age?:number
}
// 生成一个新类型要求属性从可选变必填(Required_首字母要大写)
// 使用新类型 (两种方式)
type IType = Required<Demo>
let my1:IType={
  name:'必填',
  age:1
}
//  2,直接加在用类型的地方前面
let my2:Required<Demo>={  //使用较多
  name:'必填',
  age:1
}

@Entry
@Component
struct GongJuleiPartial {

  build() {
   Column(){}
    .height('100%')
    .width('100%')
  }
}

Readonly<Type>属性只读

// 工具类
//Readonly  Readonly<Type> 作用:将属性变为只读
interface Demo{
  name:string
  age:number
}
// 将属性变为只读 不可修改(Readonly_首字母要大写)
// 使用新类型 (两种方式)
// 1,起别名
type onlyRead = Readonly<Demo>
let my1:onlyRead={
  name:'必填',
  age:1
}
// 2,直接加在用类型的地方前面
let my2:Readonly<Demo>={
  name:'必填',
  age:1
}//使用较多
console.log(``,JSON.stringify(my2))
// my2.name='修改'——>报错,因为加了Readonly已读

@Entry
@Component
struct GongJuleiPartial {

  build() {
   Column(){}
    .height('100%')
    .width('100%')
  }
}

Record<Type>构建对象新类型

// 工具类-Record<keys,Type> 作用:构建一个对象类型
// keys规定对象中属性名的类型
// type规定对象中属性值的类型
interface Type{
  name:string
  age:number
}

//联合类型——>在一组范围内取值
type keys='柯基'|'大黄'|'串串'|'金毛'

let obj:Record<keys,Type> ={
  '柯基':{name:'柯基',age:1},
  '大黄':{name:'柯基',age:1},
  '串串':{name:'柯基',age:1},
  '金毛':{name:'柯基',age:1},
}
// 取值 对象[属性]
console.log(``,JSON.stringify(obj[ '柯基']))// {"name":"柯基","age":1}
console.log(``,obj[ '大黄'].name)// 柯基


@Entry
@Component
struct GongJuleiPartial {

  build() {
   Column(){}
    .height('100%')
    .width('100%')
  }
}

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐