VueBloghyhero6

TS 泛型

2024-08-11 / 2024-08-11 / 45次浏览
泛型在定义,主要是方便后续扩展属于是既要又要范畴的,为什么这么说,因为这个接口如果定死了string,number类型,那么在后期的处理当中,业务一旦扩展,要么另外立函数要么涂抹修改接口泛型约束的背景需求产生就是这方面。

function indentity<T>(arg: T): T {
    return arg
}

定义泛型参数,要求返还参数与定义参数一致。
这就比如说定义了一个类型参数

function indentity(arg: number): number {
    return arg
}

要求返还类型是 数字类型,泛型也作为扩展之一,怎么理解这部分的问题,就是类型定义的扩展
我说一个题外话吧关于业务开发的,常规强类型语言对于类型限制的确定要页面输出端为什么不那么在意,因为大多数接口函数和业务函数最终判断给到页面显示了,如何理解,因为无论是后端或者线上合约端,给出的接口必须是确定的因为这个输出参数可能作为下一个接口,或者作为请求接口给出到接口对接,必须严格输出。而页面端作为终端输出,最终转换显示数据,并没有下一个对接人了,这也是JS 没有TS 依旧能开发这么多年的理由,万事万物皆有成因。但不能不作为不严格限制强类型的理由。

上一轮业务中使用了泛型的接口定义,但是基本很少限制函数输出
使用泛型定义的时候,基本很少情况下输入与输出保持一致,比如给出输入是string,输出类型可能则为array,直接返回一个参数数组。

function transform<TIn, TOut>(arg: TIn): TOut {
    // 需要定义返回值
    return arg as unknown as TOut; // 类型断言为TOut
}

也就是说该函数拥有双泛型参数
例如强制输出参数转换为数组

function transform<TIn, TOut>(arg: TIn): TOut {
    // 需要定义返回值
    return ([] as unknown) as TOut; // 伪装类型输出[]
}

const result = transform<string, number[]>('hello');
console.log(result) // 输出是[]

在比如这个明确目标是字符串转数组

function transform<TIn, Tout>(arg: TIn): TOut {
    if (typeof arg === "string") {
        // 字符串转数组
        return arg.split("") as unknown as TOutput;
    }
    throw new Error("Unsupported input type");
}

const result = transform<string, string[]>('hello');
console.log(result) // 输出['h', 'e', 'l', 'l', 'o']

其实还是用到了 typeof 去做一把类型判断。 还是要明确你要定义什么类型
as unknown 作为未知类型比 any更安全

业务中还是定义了泛型接口的使用更多一些

泛型约束,定义泛型接口,比如必须包含 .length 属性, 然后使用接口配合 extend 属性就行泛型约束

interface arrlength {
    length: number;
}

function login<T extend arrlength>(arg: T): T {
    console.log(arg.length);
    return arg;
}
约束函数参数必须有length 属性
login({length: 10, value: 3});