进阶之路 类型别名(type)的使用 接口(interface)的声明的使用 联合类型和交叉类型 类型断言 非空类型断言 字面量类型的使用 类型缩小(类型收窄) TypeScript 函数类型 函数类型表达式 内部规则检测 函数的调用签名 如何选择他们? 参数的可选类型 参数的默认值 剩余参数 函数重载 函数重载-联合类型(优先使用)
类型别名(type)的使用
type myname = number | string
function hander1 ( name: myname) { console . log ( name) if ( typeof name === 'string' ) { console . log ( name. length) }
}
function hander2 ( x: number , y: number , z? : number ) {
}
type myx = { x: number , y: number , z? : number }
function hander3 ( mytype: myx) {
}
接口(interface)的声明的使用
关键字使用interface声明 相比较类型别名,少了=
interface myX2 { x: number y: number z? : number
}
function hander4 ( mytype: myX2) {
}
二者区别:
类型别名和接口声明非常相似,在定义对象的时候,可以任意选择使用 主要区别: type类型使用范围更广 type定义的是别名,不允许两个相同名称的别名使用
type myname = number | string
1,接口类型只能用来声明对象 2,接口类型声明对象的时候可以多次声明 3,接口类型支持继承 4,接口类型支持被类实现
interface myX2 { x: number y: number
}
interface myX2 { z? : number
}
function hander4 ( mytype: myX2) {
}
interface myX2 { x: number y: number
}
interface myX3 extends myX2 { z? : number
}
function hander5 ( mytype: myX3) { console . log ( mytype. x, mytype. y, mytype. z)
}
hander5 ( { x: 1 , y: 2 , z: 3 } )
联合类型和交叉类型
联合类型
ts允许我们使用多种运算符,从现有类型中构建新类型 联合类型由两个或多个类型组成的类型 表示可以是这些类型中的任何一个值 联合类型中的每一个类型被称为联合成员
function hander ( name: number | string ) { console . log ( name)
}
hander ( 1 )
hander ( "123" )
let nainfo: number | string = "abc"
nainfo = 1
nainfo = "123"
function hander1 ( name: number | string ) { console . log ( name) if ( typeof name === 'string' ) { console . log ( name. length) }
}
hander1 ( 1 )
hander1 ( "123" )
注意: 在拿联合类型的值之后,因为它可能是任何一种类型,如何使用呢? 类似拿到的是number,就不能使用string的一些方法 解决: 需要使用缩小集合,也就是类型缩小,根据缩小的代码,推断出更加具体的类型
交叉类型
交叉类型表示需要满足多个类型的条件 交叉类型使用&符号
type myY = number & string
type myY2 = number & string interface myX2 { x: number y: number
}
interface myX3 { z? : number p : ( ) => void
}
const info: myX2 & myX3 = { x: 1 , y: 2 , p : ( ) => { console . log ( "方法" ) }
}
类型断言
有时候ts无法获取具体额度类型信息,这个时候需要使用类型断言 ts只允许类型断言转换为更具体的或者不太具体的类型版本,此规则可防止不可能的强制转换
获取DOM元素
const imgE1 = document. querySelector ( "img" )
if ( imgE1 != null ) { imgE1. src = ""
}
const imgE2 = document. querySelector ( ".img" ) as HTMLImageElement
imgE2. src = ""
const num = 12
const num2 = num as any
也可以继续,将不太具体的类型类型断言成更具体的样子 但不支持这样来回断言,有安全隐患
const num = 12
const num2 = num as any
const num3 = num2 as string
非空类型断言
当传入的值有可能为undefined时,这个时候方法不能执行 采用符号!,必须确保某个标识符是有值的,可以跳过ts在编译阶段对它的检测
interface hander { name: string , age: number , size? : number
}
const info: hander= { name: "乞力马扎罗" , age: 18
}
console . log ( info?. size)
if ( info. size) { info. size= 23
}
info! . size= 23
console . log ( info. size)
字面量类型的使用
将赋予的值当做类型,使用的时候只能使用字面量 默认情况下没有多大意义,但是可以将多个类型联合在一起,你只能是我们中一个
type numtype = "left" | "top" | "up"
const num3: numtype = "left"
type requestype = "get" | "post"
function reqest ( url: string , method: requestype) { }
reqest ( 'http//xxx.com' , 'get' )
type requestype = "get" | "post"
function reqest ( url: string , method: requestype) { }
const hander= { url: 'xxx' , method: 'post'
}
reqest ( 'http//xxx.com' , hander. method as "post" )
const hander1 : { url: string , method: 'post' } = { url: 'xxx' , method: 'post'
} as const
reqest ( 'http//xxx.com' , hander1. method)
const hander2= { url: 'xxx' , method: 'post'
} as const
reqest ( 'http//xxx.com' , hander2. method)
类型缩小(类型收窄)
if ( info. size) { info. size= 23
}
类似这样的语句也称之为类型保护 在给定的执行路径中,可以缩小比声明时更小的类型,这个过程称之为缩小 常见的类型保护 typeof,检查返回的类型
type requestype = "get" | "post"
function reqest ( url: string , method: requestype) { if ( typeof url === 'string' ) { console . log ( url) }
}
平等缩小(=== 和!== 和==等等),字面量的判断
type requestype = "get" | "post"
function reqest ( url: string , method: requestype) { if ( method=== "get" ) { console . log ( method) }
}
function reqest ( data: string | Date) { if ( data instanceof Date ) { console . log ( data. getTime ( ) ) }
}
in ,用于确定对象是否具有带名称的属性,in 运算符 等等…
TypeScript 函数类型
函数类型表达式
可以编写函数类型的表达式,来表示函数类型 ts中,函数类型中的形参名是不能省略的
const fun : ( num2: number ) => number = ( arg: number ) : number => { return 123
}
type funtype = ( num2: number ) => number
const fun2: funtype = ( arg: number ) => { return 123
}
function cals ( func) { const num1 = 12 const num2 = 13 const res = func ( num1, num2)
}
function func1 ( num1, num2) { return num1 + num2
}
cals ( func1)
type calstype = ( num1: number , num2: number ) => number
function cals1 ( func: calstype) { const num1 = 12 const num2 = 13 const res = func ( num1, num2)
}
function func2 ( num1: number , num2: number ) { return num1 * num2
}
cals1 ( func2)
内部规则检测
interface gule { name: string age: number
}
const p = { name: "山头" , age: 12 , size: '大'
}
const info: gule = p
函数的调用签名
在js中,函数除了可以被调用,自己也可以有属性值的 类型表达式并不能支持声明属性 当你想要一个带有属性的函数,就可以在一个对象类型中写一个调用签名
type obj2 = ( num1: number ) => number
interface obj { name: string age: number ( num1: number ) : number
} const func: obj = ( num1: number ) : number => { return 123
}
func ( 123 )
如何选择他们?
如果只是描述函数类型本身(函数类型可以被调用),使用函数表达式 如果再描述函数作为对象可以被调用,同时也有其他属性时,使用函数调用签名
参数的可选类型
function fun ( x: number , y? : number ) { console . log ( x, y) if ( y!= undefined ) { console . log ( y) }
}
fun ( 1 )
参数的默认值
function fun ( x: number , y= 100 ) { console . log ( x, y) if ( y!= undefined ) { console . log ( y) }
}
fun ( 1 )
剩余参数
剩余参数语法允许我们将一个不定数量的参数表示为一个数组。 利用剩余参数我们可以定义一个形参不固定的计算和的函数。
function sum ( first, ... args) { console . log ( first) ; console . log ( args) ;
}
sum ( 10 , 20 , 30 ) ;
function fun ( ... arrs: ( string | number ) [ ] ) { }
fun ( 1 , 2 , 3 , '4' )
函数重载
ts中,可以去编写不同的重载函数,来表示函数可以以不同的方式进行调用 一般是编写两个或者以上的重载签名。再去编写一个通用的函数以及实现
function add2 ( n1: number , n2: number ) : number
function add2 ( n1: string , n2: string ) : string
function add2 ( n1: any , n2: any ) { return n1 + n2
}
console . log ( add2 ( 1 , 2 ) )
console . log ( add2 ( "1" , "2" ) )
函数重载-联合类型(优先使用)
function add2 ( arg: string | any [ ] ) { return arg. length
}
console . log ( add2 ( "123" ) )