TypeScript泛型

泛型

一般的广泛的不需要预先定义的数据类型,需要在使用的时候才会确定数据类型
泛型可以接受任何类型的值,输入和输出的类型一致。

创建泛型函数

泛型约束函数

function log<T>(value:T):T{
	return value
}
//在调用时需要指定参数的类型
log<string[]>(["a","b"])

创建泛型函数类型

type Log=<T>(value:T)=>T
let myLog:Log =(value)=>value

创建泛型接口

泛型约束接口

interface Loge<T>{
	<T>(value:T):T
}
let myLog:Loge<number> = (value)=>value

泛型类

泛型约束类

class Log<T>{
	run(value:T){
		return value
	}
}
let log1=new Log<number>()
log1.run(1)

泛型约束

interface Length{
	length:number
}
function log<T extends Length>(value:T):T{
	console.log(value,value.length)
	return value
}

泛型的用处

  1. 函数和类可以轻松地支持多种类型,增强程序的扩展
  2. 不必写多条函数重载,荣昌的联合类型声明,增强代码可读性
  3. 灵活控制类型之间的约束

类型检查机制

TypeScript编译器在做类型检查时,所秉承的一些原则,以及表现出的一些行为。
作用:辅助开发,提高开发效率

类型推断

不需要指定变量的类型或函数返回值的类型,TypeScript可以根据某些规则自动的为其推断出一个类型

基础类型推断

初始化变量时,如果不指定类型,会自动推断为any,如果赋值为1,则会推断为number类型
设置函数默认参数时,如果默认为1则推断为number
在设置函数返回值时返回1则推断为number

最佳通用类型推断

上下文类型推断

从左到右推断,发生在事件处理中,当我们通过事件对象打印不属于当前元素的属性时报错

类型兼容性

当一个类型y可以被复制给另一个类型x时,我们就可以说类型x兼容类型y

接口兼容性

interface X{
	a:any;
	b:any;
}
interface Y{
	a:any;
	b:any;
	c:any;
}
let x:X={a:1,b:2}
let y:Y={a:1,b:2,c:3}
x=y

根据以上代码,x兼容y,y包含x,属性少的兼容属性多的。

函数兼容性

参数个数的兼容

type Handle=(a:number,b:number)=>void
function hof(handle:Handle){
	return handle
}

let handler = (a:number)=>{}
hof(handler)//handler可以兼容handle
let handler2 = (a:number,b:number,c:number)=>{}
hof(handler2)//handler2不能兼容handle

固定参数兼容可选参数和剩余参数
可选参数不兼容固定参数和剩余参数
剩余参数可以兼容固定参数和可选参数
参数类型的兼容

interface Point3D{
	x:number;
	y:number;
	z:number;
}

interface Point2D{
	x:number;
	y:number;
}
let p3d=(point:Point3D) =>{}
let p2d=(point:Point2D) =>{}
p3d=p2d//兼容
p2d=p3d//不兼容

返回值类型

let f= ()=>({name:"Alice"})
let g = ()=>({name:"Alice",age:100})
f=g
g=f

类型保护

enum Type{Strong,Week}
class Java{
	helloJava(){
		console.log("hello Java")
	}
}
class Javascript{
	helloJavascript(){
		console.log("hello javascript")
	}
}

function getLanguage(type:Type){
	let lang=type===Type.Strong?new Java():new Javascript()
	if((lang as Java).helloJava){
		(lang as java).helloJava()
	}else{
		(lang as javascript).helloJavascript()
	}
	return lang
}

在这个例子中我们对type进行类型判断是如果是java就执行java类中的放法,如果是JavaScript就执行JavaScript类中的放法。使用以前的知识我们可以类型断言实现。
ts中也有类型保护,也可以实现,类型保护是指ts提前对类型做出预判,ts能在特定的区块中保证变量属于某种确定的类型,可以在此区块中放心的引用此类型的属性,或者调用此类型的方法。
创建这个区块的方法有四种

  1. instanceof
function getLanguage(type:Type,x:string|number){
	let lang=type===Type.Strong?new Java():new Javascript()
	// instanceof
	if(lang instanceof Java){
		lang.helloJava()
	}else{
		lang.helloJavascript()
	}
	return lang
}
  1. in
function getLanguage(type:Type,x:string|number){
	let lang=type===Type.Strong?new Java():new Javascript()
	//in
	 if("java" in lang){
		lang.helloJava()
	}else{
		lang.helloJavascript()
	} 
	return lang
}
  1. typeof
function getLanguage(type:Type,x:string|number){
	let lang=type===Type.Strong?new Java():new Javascript()
	//typeof
	if(typeof x === "string"){
		return x.length
	}else{
		x.toFixed(2)
	} 
	return lang
}
  1. 通过创建类型保护函数
//下面这个函数的返回值叫做类型类词
function isJava(lang:Java|Javascript):lang is Java{
	return (lang as Java).helloJava !== undefined
}
function getLanguage(type:Type,x:string|number){
	let lang=type===Type.Strong?new Java():new Javascript()
	if(isJava(lang)){
		lang.helloJava()
	}else{
		lang.helloJavascript()
	}
	return lang
}

你可能感兴趣的:(typescript,typescript)