进阶之路
- 类型别名(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")) |
复制