类型推论
声明一个变量,但是没有定义类型
TypeScript 会在没有明确的指定类型的时候推测出一个类型,这就是类型推论
let str = '你好世界'
// str=123 //报错:根据上面声明变量并且已赋值则推论出字符串数据类型,下面再赋值其他数据类型则会报错
let a //如果不赋值情况下 typeScript会推断出是一个any类型可以进行任何操作
a=[],
a={},
a=true //所以赋什么值都不会报错
类型别名
type 关键字(可以给一个类型定义一个名字)多用于复合类型
//定义类型别名
type s = string
let str:s='张三'
//定义联合类型别名
type u = string | number
let str:u= 456
let str1:u= '你好'
let str1:u= true //报错不可以给boolean值
//定义函数类型别名
type cd= ()=>string
const fn :cd=()=>'你好世界'
//定义值得类型别名
type T = 'off' | 'on' | false
// let str:T=123 //报错
let str:T='off'
泛型
function num(a:number,b:number):Array<number>{ //普通方法
return [a,b]
}
num(1,2)
function add<T>(a:T,b:T):Array<T>{
return [a,b]
}
add<number>(1,2) //想返回number类型就可以返回number类型
add<string>('你好','世界') //想返回string类型就可以返回string类型
//好处 ,当定义函数时不确定类似,当使用的时候再确定类型
//缩写: typeScript是会进行类型推论
add(1,2)
add('1','2')
//定义多种数据类型的泛型
function sub<T,U>(a:T,b:U):Array<T | U>{
let arr:Array<T | U> = [a,b]
return arr
}
sub<number,boolean>(1,false)
定义多种数据类型的泛型
function sub<T,U>(a:T,b:U):Array<T | U>{
let arr:Array<T | U> = [a,b]
return arr
}
sub<number,boolean>(1,false)
泛型的约束
interface Len{
length:number
}
function getLength<T extends Len>(arg:T){
return arg.length
}
// getLength(123) //报错,因为数字身上没有length属性
getLength('123') //ok 传字符串或者数据都可以,传数组或者Boolean会报错
使用keyof约束对象 and 泛型类
function prop<T>(obj:T,key){ //默认的是这种不会报错
return obj[key]
}
let o = {a:1,b:2,c:3}
prop(o,'a')
prop(o,'d') //这种情况查不出d应该报错提示的,但是并没有
//所以使用keyof方法进行约束
function prop<T,K extends keyof T>(obj:T,key:K){
return obj[key]
}
let o = {a:1,b:2,c:3}
prop(o,'a')
prop(o,'d') //此时就会报错:类型“"d"”的参数不能赋给类型“"a" | "b" | "c"”的参数。
//:其中使用了TS泛型和泛型约束。首先定义了T类型并使用extends关键字继承object类型的子类型,然后使用keyof操作符获取T类型的所有键,它的返回类型是联合类型,最后利用extends关键字约束K类型必须为keyof T联合类型的子类型
泛型类
class Sub<T>{
attr:T[]=[];
add(a:T):T[]{
return [a]
}
}
let s= new Sub<number>()
// s.attr=['46532'] //报错
s.attr=[1,2,3] //可以
s.add(213)
let str= new Sub<string>()
str.attr=['1','2','3']
str.add('213')
console.log(s,str);
//Sub { attr: [ 1, 2, 3 ] } Sub { attr: [ '1', '2', '3' ] }