TS-泛型

TS-泛型

1.当需要 定义 一个 参数 类型 与 返回 值 类型 不确定的 函数 时:

  • 使用 any
function test(name:any):any{
	console.log('this is 泛型 demo');
	/*
		...
	*/
	return name
}
test(123);
使用 any  定义 时  存在 问题: 虽然 可以 知道 传入值 的类型 但是  无法 获取 函数 返回 值 的 类型 。

这 个 问题 可以 用 泛型 很好 的解决。

2.泛型定义:

  • 泛型 是 指 在 定义 函数 /接口 / 类 时,不预先 指定 具体 的 类型,而是 在 使用 的 时候 再 指定 类型限制 的 一种 特性。
  • 用法:
    使用 方法 一:
function test<T>(name:T):T{
	console.log('hellow 泛型');
	/*
		...
	*/
	return name;
}
test<number>(123);   //  最终 返回 值 是 number 类型

//定义 多个 类型
test<number|string>(123);  //  返回 值为 number 类型     可以 传入 字符串 或者  数值 类型
//类型 之间 用 | 符号 分隔

使用 类似 于 函数 传参,传 什么 数据 类型 则 T 表示 什么 数据类型,使用 <…> 表示。T也可以 换成 任意 字符。

若指定 了 返回 值为 泛型 如 上述函数 ,则 函数 必须 返回 任意类型,即 返回值 类型 不可以 是 明确 规定 的 类型,注意 隐式转换。
eg:

function test<T>(name:T):T{
	console.log('hellow 泛型');
	/*
		...
	*/
	return name+'aaa';   // error          because 字符串 + 任何 数据 都等于 字符串  所以 这里 相当于 固定了 返回 值 为 字符串
}

使用 方法 二:
类型 推断

//直接调用 不传 泛型 实参
test(123);  // 此时 相当 与   test<number>(123)       编译器 会 自动识别 传入 的 参数 ,将 传入 的 参数  类型 认为 是 泛型 指定 的 类型

//若 函数 有 2个 及 以上 参数  且 有 2个 及 以上 参数 指定的 类型 都为 泛型
function test<T>(name:T,age:T):T{
	return name;
}
//此时 类型 推断 会 默认 将 第一个 参数 的 数据类型 作为 泛型 指定的 类型
test(123,'111'); //error  此时 必须 传 numbe 类型

注意:使用 泛型 会相当 容易 出错 ,所以 看情况 使用 ,不要 什么 都使用 泛型。
eg: 当 一个 函数 的 参数 使用 泛型 限制 类型 时,则 在 该 方法 内 此 参数 使用 的 方法 必须是 所有 类型 通用 的 方法 ,否则会报错。

function test<T>(titile:T,name:T):boolean{
	let  index = title.indexOf(name);    // error     indexOf  number boolean等 类型  不能 使用  
	return index === -1;
}
  • 在 接口 中 使用 泛型
interface Search {
	<T>(name:T,age:T):boolean
}
let fn:Search =  function <T>(name:T,age:T):boolean{
	return  name === age;
}
fn<string>('111','222');
  • 泛型 在 类 中 的 运用
class  Animal <T>{    // 此处 的 泛型 为 限制 构造 函数参数 类型  以及  类 成员 变量 的 类型
	name:T;
	constructor(name:T){
		this.name = name;
	}
	action<T>(say:T):T{//  此处 为  限制 类 中 成员 方法 action    若 此处 不写 <T> 则 使用 类 声明的 <T>
		return say;
	}
}
let dog = new Animal<string>('dog');        // 此处 的 striing 为 限制 构造 函数参数 类型  以及  类 成员 变量 的 类型
dog.action<number>(123); //  此处 为  限制 类 中 成员 方法 action   
  • 扩展:
    (1).约束泛型 使用 接口 约束 泛型
    使用 extends 用于 约束 泛型 如下:
interface LengthNum {
	length:number;
}
function fn<T extends LengthNum>(name:T):T{
	return name
}
//  此时  相当于 约束 了 泛型 的 类型 必须 是 含有 length 属性 的 数据类型
fn<number>(123);// error     number 类型 没有 length 属性

fn<string>('111'); // success   string 类型 有 length 属性

fn<object>({}); //error    object 类型 没有 length 属性

(2).数组 泛型

let arr: Array<number> = [1,2,3,4];     ===    let arr: number[] = [1,2,3,4]

写一个 稍微复杂的 例子:

function createArray<T>(length:number,value:T):Array<T>{
		let  result: T[] = [];
		for(let i=0;i<length;i++){
			result.push(value);
		}
		return result;
}
createArray<string>(3,'x');   //   此时 表示 该 函数 必须 返回 一个 字符串 数组

注意:
1.函数 在定义 时 若 指定 返回 值 不为 void 或者 any 则 在函数 内 必须 写 return

发布了96 篇原创文章 · 获赞 64 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/qq_41709082/article/details/96855514