TS03

295 阅读3分钟

泛型

// 接口描述当前的实例 描述构造函数
// 单例模式

interface IMq<T>{ // 泛型就是调用的时候才能确定类型。  
    new ():T // 用构造函数描述类 //返回的是Mq这类的实例 构造函数张这个模样的类都能传,这样就有问题糊传就很麻烦。 Mq 这个不能写死 需要用到泛型 什么类进去返回什么实例。
}

class Mq{
    constructor(){

    }
}


// function createMq(mq:IMq<Mq>){ // 用接口描述构造函数
// function createMq(mq: new ()=>Mq){
function createMq(mq: {new ():Mq}){ 


}
createMq(Mq)

function createArray<T>(times:number, ct:T):T[]{
    let res = [];
    for(let i = 0; i < times; i++){
        res.push(ct)
    }

    return res;
}

createArray<number>(3, 123);

// number 不传递会根据123推断出来这个是个number

// 泛型的多个类型 <T,K,xxxxx>

// 元组类型交换是个什么鬼?

function swap<T,K>(ay:[T, K]):[K, T]{
    const res:[K, T] = [
        ay[1],
        ay[0]
    ];

    return res;
}

swap(['abc', 123]) // 希望返回结果是 [123,'abc'] 靠着默认推断TK 默认还是比较灵活写死泛型比较呆板。

type FTYPE<T> = <T>()=>T[] // 在前面要一个T // 如果泛型不传参数是unknow,注意第一个T是用这个类型时候传递的T类型 第二个是使用函数的时候传递的 这两个不是一个内容


// 箭头函数的泛型接口 const FT:<T>()=>T[] = <T>():T[] => {}

// 类型不确定首要就是想到泛型

// 接口的泛型

interface JKDFZ<T> { // 这个 T 这个作用域整个接口 使用接口的时候就确认T
    <T>(T:a):T // 这个 T 也不是一个 这个值作用域这个函数 使用函数的时候在确定T
}

// 泛型约束
function sa<T extends string>(a:T, b:T):T{ // 一般用约束对象。 就是约束一下泛型
    return (a+b) as T; // 如果报错需要断言
}

// 如果想计算两个length属性相加怎么鼓捣?
interface ObjLen {
    length:number;
}

function getObjLen<T extends ObjLen, K extends ObjLen>(a:T, b:K):number{
    return a.length+b.length;
}

// ts获取属性约束 获取对象所有的k
// keyof 取出目标所有的key 变成联合类型
// in 

interface S {
    a:number;
    b:number;
}

let s:S = {a:1,b:2}

type lh = keyof S;
type ay = keyof any; // string | number | symbol
type lh2 = keyof {a:1,b:2}; // 在type中玩的是类型 {a:1,b:2} 这个就解释成了 a的类型1 而不是 a的值是1 直接撸类型的key 


let sak:lh = 'a'

function getVal<T extends object, K extends keyof T>(){

}
getVal({a:1,b:2}, 'b')



never void

// 肯定达不到终点,需要手动的标识一下。 

// 自己推断出来的 不可达的

// 类中的void 标识不关心返回值类型, 比如接口定义的方法返回void 实现类实现写了个返回string 没问题的

// 函数的void就是什么也没有 他可以承接undefined 严格类型 严格模式一定要开启

// 使用联合类型会先赋值在调用赋值后的值类型的方法。 

// 函数会自动推断返回值类型。

let obj = {
    name: '',
    age: 12
}

type ObjType = typeof obj // 直接就把obj的接口抽离出来了,偷懒的办法 这个玩意叫类型反推 用的不多。

// 接口可以继承类 把方法都掏出来

// 类的类型是描述实例的 如何描述类接收类 {new ():类}

class Test{

}
// 可以这么来 把这个类的类型拿出来
function createTest(clazz: typeof Test){ // typeof 后面要是个值 Test 类的本身 typeof Test
                                         // typeof T 这里是个类型所以不能这么玩 typeof 类型不行

}

function createTest(clazz: new ()=>Test){

}
function createTest(clazz: {new ():Test}){

}

// 类的类型用 new ()=>xxx来接收类