《深入鸿蒙泛型:多泛型协同、约束机制及工具类型底层逻辑》
·
泛型简述
泛型:指在定义时不会设置具体类型,在使用时再进行类型的定义(通俗一点就是:类型是可变的!)
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%')
}
}

更多推荐




所有评论(0)