10、泛型(Generics)

10、泛型(Generics)概念:泛型(Generics)是指在定义函数、接口或者类的时候,不预先指定其类型,而是在使用是手动指定其类型的一种特性10.1、使用场景我们需要创建一个函数,这个函数会返回任何它传入的值。functionidentity(arg:any):any{returnarg}id

大家好,欢迎来到IT知识分享网。10、泛型(Generics)

  • 概念:泛型(Generics)是指在定义函数、接口或者类的时候, 不预先指定其类型,而是在使用是手动指定其类型的一种特性

10.1、使用场景

我们需要创建一个函数, 这个函数会返回任何它传入的值。

function identity (arg: any): any {

return arg

}

identity (3) // => 3

这样代码编译不会出错,但是存在一个显而易见的缺陷,就是没办法约束输出的类型与输入的类型保持一致

 

这时可以用泛型来解决这个问题

function identity<T>(arg: T): T {

    return arg

}

identity(3) // => 3

上例中我们在函数名字后面价一个<T>,其中的 T 表示任意输入的类型,后面的 T 即表示输出的类型,且与输入        保持一致

 

当然我们也可以在调用时手动指定输入与输出的类型, 如上述函数指定

identity<number>(3) // => 3

 

10.2、泛型约束

在泛型函数内部使用类型变量时, 由于事先并不知道它是那种类型, 所以不能随意操作它的属性和方法

function identity<T>(ary: T): T {

console.log(arg.length) // => err

return arg

}

上述函数中 类型 T 上不一定存在 length 属性, 所以编译的时候就报错了。

 

这时,我们可以的对泛型进行约束,对这个函数传入的值约束必须包含 length 的属性, 这就是泛型约束

interface lengthwise {

length: number

}

function identity<T extends lengthwise> (arg: T): T {

console.log(arg.length) // => err

return arg

}

identity({a: 1, length: 1}) // => 1

identity(‘str’) // => 3

identity(6) // => err 传入是参数中未能包含length属性

这样我们就可以通过泛型约束的方法对函数传入的参数进行约束限制。

 

多个参数时也可以在泛型约束中使用类型参数

如你声明了一个类型参数, 它被另一类型参数所约束。现在想要用属性名从对象里湖区这个属性。并且还需确保这个属性存在于这个对象上, 因此需要咋这两个类型之间使用约束,

简单举例来说: 定义一个函数, 接受两个参数 第一个是个对象 obj,第二个个参数是第一参数 key 是对象里面的键名, 需要输入obj[key]

function identity <T, K extends keyof T>(obj: T, key: K) {

return obj[key]

}

let obj = { a: 1, b: 2, c: 3 }

identity(obj, ‘a’)  // => success

identity(obj, ‘m’) // => err obj 中不存在 m 这个参数

10.3、泛型接口

之前学过可以使用接口的方式来定义一个函数需要符合的形状

interface SearchFunc {

(source: string, subString: string): boolean;

}

let mySearch: SearchFunc;

mySearch = function(source: string, subString: string) {

return source.search(subString) !== -1;

}

 

当然也可以使用含有泛型的接口来定义函数的形状

interface CreateArrayFunc {

<T>(length: number, value: T): Array<T>;

}

let createArray: CreateArrayFunc;

createArray = function<T>(length: number, value: T): Array<T> {

let result: T[] = [];

for (let i = 0; i < length; i++) {

result[i] = value;

}

return result;

}

createArray(3, ‘x’); // => [‘x’, ‘x’, ‘x’]

 

进一步,我们可以把泛型参数提前到接口名上

interface CreateArrayFunc<T> {

(length: number, value: T): Array<T>;

}

let createArray: CreateArrayFunc<any>;

createArray = function<T>(length: number, value: T): Array<T> {

let result: T[] = [];

for (let i = 0; i < length; i++) {

result[i] = value;

}

return result;

}

createArray(3, ‘x’); // =>  [‘x’, ‘x’, ‘x’]

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/33062.html

(0)

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信