Typescript:
介绍:
TypeScript(简称 TS)是JavaScript的超集(继承了JS全部语法),TypeScript = Type + JavaScript。
- 简单说,就是在JS的基础上,为JS添加了类型支持。
- 是微软开发的开源编程语言,可以在任何运行JavaScript的地方运行。
类型注解:
类型注解:是指在变量、函数等定义的时候,使用特定语法(: type)来指定其类型,并在代码中限制只能接收特定类型的值。
为什么要使用TypeScript?
示例:
TypeScript快速入门:
准备:
安装TS官方提供的编译器:npm install -g typescript (管理员身份运行,只需要做一次即可)
npm install -g typescript
找到cmd以管理员身份打开:
输入指令:
编码:
- 定义ts文件,定义变量,指定类型注解
- 编译ts文件,测试程序运行
创建一个demo.ts的文件编写ts:
let uname:string = 'sundaoen'
let count:number = 18;
console.log(`uname = ${uname} ------>count = ${count}`);
注意浏览器不能直接解析,ts文件。需要转换成js文件,浏览器才可以执行。
运行:
语法:
tsc 要执行的ts文件
示例: tsc demo.ts
注意:TS代码编译目标版本为es3(比较低),可以通过参数 -target 指定编译的目标版本。如 es5,es6,es2016,esnext
创建1.html文件,引入demo.ts测试:
我先不 tsc 编译ts代码,看看浏览器会出现什么错误。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>tsrumen</title>
</head>
<body>
<script src="../ts/demo.ts"></script>
</body>
</html
在浏览器里面测试:
浏览器报错了,无法识别。
在引入 ts文件的时候,需要先把,ts文件,转换成 js文件。
打开vs code的控制台,点击一个向下的箭头,在选择Command Prompt
这样就打开cmd控制台了。
输入指令:
回车之后,可以看到多了一个 demo.js文件
在 1.html引入 demo.js在浏览器测试:
现在就不报错了
看看我们刚刚编译出来的 demo.js文件:
可以发现,还在用var来声明变量。这是因为ts编译目标版本为es3,版本太低了。
使用以下指令,切换ts编译的版本。
语法:
tsc -target 版本 目标ts文件
示例:
tsc -target esnext demo.ts
重写编译demo.ts文件:
再次打开demo.js文件看看:
在浏览器看看效果:
TypeScript类型注解分类:
基础类型:
- 数字类型:number
- 字符类型:string
- 布尔类型:boolean
- null/undefined:null/undefined
- 任意类型:any(不推荐)
- 原则上,不推荐使用any!!! 这会让TypeScript又回到JavaScript(失去TS类型保护的优势)。
- 数组类型:number[]/string[]/Array<number>/Array<string>
定义 demo1.ts文件,来测试:
//定义一个 string类型的变量
let uname:string = 'jack'
uname=10
看看错误提示:
在测试一次,这次声明一个number类型的变量。
//定义一个number类型的变量
let ucount:number = 10
ucount = '你好'
看看报错提示:
可以发现,我们使用ts在定义变量的时候,会指定一个变量的类型。比如number类型或者number类型,当我们不按照指定类型赋值的时候,就会报错。
//定义一个 string类型的变量
let uname:string = 'jack'
//定义一个number类型的变量
let ucount:number = 10
//定义一个布尔类型的变量
let flag:boolean = true
flag = false
//定义一个null类型的变量
let nullValue:null = null
//定义一个undefined类型的变量
let undeValue:undefined = undefined
//定义一个any类型的变量,里面额度值可以是任意的。
let abs:any = 12;
abs = 'any 是任意类型的'
//定义一个number类型的数组
let numArr:number[] = [1,2,3,4,5]
//定义一个string类型的数组
let strArr:string[] = ['a','b','c']
//定义一个数组添加一个泛型,泛型的类型是数组
let arrs:Array<number> = [34,65,76]
console.log(`${uname} : ${ucount} : ${flag} : ${nullValue} : ${undeValue} : ${abs} : ${numArr}
: ${strArr} : ${arrs}`);
编译 demo1.ts文件:
代码:
tsc -target esnext demo1.ts
在1.html文件引入。demo1.js文件:
在浏览器上看看效果:
注意事项:
联合类型:
介绍:
是指由两个或多个其他类型组成的类型,表示可以是其中的任意一种。
写法:
写法:类型1 | 类型2
提示:
TS中的联合类型中指定的多种类型之间使用 | 分隔,建议使用()括起来
定义一个demo1.ts文件:
代码:
//定义一个联合类型的变量,命名为strAndnum,表示可以为sring类型也可以为number类型
let strAndnum:(string | number) = 10
strAndnum = 'sundoaen'
我在定义一个联合类型的数组变量,包含布尔和srting类型:
代码:
//定义一个boolean类型的数组变量,包含布尔和string
let boolAndStrArr:(boolean | string)[] = [true,'a','b']
在上面定义的boolAndArr的 数组变量中,在存储这两个类悉尼港之外的数据,看看效果:
错误提示:
类型别名:
类型别名:
相当于一种自定义类型,为任意类型起别名。
使用场景:
当同一类型(复杂)别多次使用时,可以通过类型别名,简化该类型(复杂)的书写。
定义语法:
type customType = 指定类型
代码:
//起别名
type numAndStrArr = (number | string)[]
//使用别名定义变量
let aa:numAndStrArr = [1,2,3,'as','ak']
错误演示:
代码:
//起别名
type numAndStrArr = (number | string)[]
//使用别名定义变量
let aa:numAndStrArr = [1,2,3,'as','ak',true] //此时会报错的
demo2.ts全部代码:
代码:
//联合类型
let uname:string = 'aaa'
//定义一个联合类型的变量,命名为strAndnum,表示可以为sring类型也可以为number类型
let strAndnum:(string | number) = 10
strAndnum = 'sundoaen'
//定义一个boolean类型的数组变量,包含布尔和string
let boolAndStrArr:(boolean | string)[] = [true,'a','b']
//起别名
type numAndStrArr = (number | string)[]
//使用别名定义变量
let aa:numAndStrArr = [1,2,3,'as','ak']
type str = string
let strVar:str = '别名变量'
console.log(`${aa} : ${boolAndStrArr} : ${strVar}`);
编译 demo2.ts文件:
可以看到多了一个 demo2.js文件:
现在我们把 demo2.js文件引入到1.html文件中
代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>tsrumen</title>
</head>
<body>
<script src="../ts/demo2.js"></script>
</body>
</html
在浏览器看看效果:
提示:
类型别名type,是可以为任意类型指定别名的。
小结:
函数类型:
介绍:
函数类型实际上指的是:函数的参数及返回值的类型
语法一:单独指定参数,返回值类型:
注意:
与JS不同,TS中函数调用时传入的参数个数必须与函数定义时参数个数一致。
语法二:书写完成函数类型(同时指定参数、返回值类型)
可选参数:
在TS里我们可以在参数后使用?实现可选参数的功能。而且可选参数只能出现在参数列表的最后。
提示:
如果函数没有返回值,则函数的返回值类型为:void
代码:
// 具名函数(有具体名称的函数)
function add1(x:number,y:number):number{
return x + y;
}
console.log(add1(1,3));
编译 demo3.ts文件,引入 1.html进行测试:
引入测试:
代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>tsrumen</title>
</head>
<body>
<script src="../ts/demo3.js"></script>
</body>
</html
在浏览器看看效果:
定义多个函数进行测试:
代码:
//匿名函数
let add2 = function(x:number,y:number):number{
return x + y;
}
console.log(add2(10,20))
//箭头函数
let add3 = (x:number,y:number):number =>{
return x + y
}
console.log(add3(100,200));
//无返回值的箭头函数
let add4 = (x:number,y:number):void =>{
console.log(x + y);
}
//可选参数函数
let add5 = function(first:string,last?:string):string{
if (last) {
return first + '' + last
}
return first
}
console.log(add5('java','之父'));
console.log(add5('java'));
重写编译 demo3.ts文件,进行测试:
对象类型&接口interface:
对象类型:
TS中的对象类型就是来描述对应的结构的(有什么类型的属性和方法)。
说明:
- 直接使用{}来描述对象的结构。属性采用 属性名:类型 的形式;方法采用 方法名():返回值类型 的形式。
- 如果方法有参数,就在方法名后面的小括号中指定参数类型(如:say(content:string):void)。
- 在一行中指定多个属性类型时,可以使用 逗号/分号 来分割。
- 方法的类型,也可以使用箭头函数形式,比如:say:() => void。
- 对象的属性或方法,也可以是可选的,此时就可以声明可选属性/方法,使用 ?(问号)来表示。
定义对象测试:
//定义对象
let stu1 = {
uname:'sundaoen',
age:18,
gender:1,
play(){
console.log('写代码');
}
}
//输出这个对象里面的内容
console.log(stu1.uname);
console.log(stu1.play);
编译 demo4.ts文件:
在1.html中引入,demo4.js文件进行测试:
在浏览器上看看效果:
设想一下,我们要是在定义一个和stu1一样数据类型的对象,还需要再写很多属性包括属性的类型,这样重复的代码,就显得很多。那该怎么解决呢?试试下面的接口吧。
定义接口:
介绍:
一个对象类型被多次使用时,我们可以使用 接口(interface)来描述对象的类型,达到 复用 的目的。
说明:
- 接口使用 interface 关键字来声明,接口名称可以是任意合法的变量名称。
- 接口中定义的属性或方法,结尾可以使用逗号(,)/分号(;)分隔;如果每一行只有一个属性,后面也可以不写分号(;)。
定义接口:
代码:
//假如我们还有在定义一个对象,还需要再写一大堆的,对象类型和方法参数类型和返回值。推荐使用接口
interface User{
name:string,
ages:number,
genders:number,
play():void
}
引用这个接口,定义对象:
代码:
//使用接口定义对象
let stu2:User = {
name:'java222',
ages:18,
genders:1,
play() {
console.log('interface 生成的222');
}
}
//调用使用User接口,定义的对象。
console.log(stu2.name);
console.log(stu2.play);
报错示例:
报错提示:
重新编译测试:
定义多个接口,创建多个对象测试:
在重复一遍:接口中定义的属性或方法,结尾可以使用逗号(,)/分号(;)分隔;如果每一行只有一个属性,后面也可以不写分号(;)。
//接口中定义的属性或方法,结尾可以使用逗号(,)/分号(;)分隔;如果每一行只有一个属性,后面也可以不写分号(;)。
interface Dog{
name:string;
color:string;
play?():void;
}
interface Cat{
name:string
color:string
play?():void
}
使用接口创建对象:
代码:
//使用 Dog接口
let dog1:Dog = {
name:'哈士奇',
color:'黑白相间',
//此方法可有可无
play(){
console.log('哈士奇,汪汪汪')
}
}
let dog2:Dog = {
name:'哈士奇',
color:'黑白相间',
//play方法是可选的
}
//调用dog1对象
console.log(dog1.name);
console.log(dog1.play);
重新编译测试:
使用type也可以定义:
代码:
//使用type定义的别名
type animal = {
name:string,
age:number,
play?():void
}
使用接口或者type定义的接口模板时,类型不能用错。
代码:
//使用type类型的别名
let an1:animal = {
name:"我是animal type 类型",
age:'18', //这样写会报错的
play() {
console.log('我是animal的play方法');
}
}
重写编译测试:
demo4全部代码:
代码:
//定义对象
let stu1 = {
uname:'sundaoen',
age:18,
gender:1,
play(){
console.log('写代码');
}
}
console.log(stu1.uname);
console.log(stu1.play);
//假如我们还有在定义一个对象,还需要再写一大堆的,对象类型和方法参数类型和返回值。推荐使用接口
interface User{
name:string,
ages:number,
genders:number,
play():void
}
//使用接口定义对象
let stu2:User = {
name:'java222(使用User接口创建的对象)',
ages:18,
genders:1,
play() {
console.log('interface接口(User) 创建的对象里面的方法。');
}
}
//调用使用User接口,定义的对象。
console.log(stu2.name);
console.log(stu2.play);
//接口中定义的属性或方法,结尾可以使用逗号(,)/分号(;)分隔;如果每一行只有一个属性,后面也可以不写分号(;)。
interface Dog{
name:string;
color:string;
play?():void;
}
interface Cat{
name:string
color:string
play?():void
}
//使用 Dog接口
let dog1:Dog = {
name:'哈士奇',
color:'黑白相间',
//此方法可有可无
play(){
console.log('哈士奇,汪汪汪')
}
}
let dog2:Dog = {
name:'哈士奇',
color:'黑白相间',
//play方法是可选的
}
//调用dog1对象
console.log(dog1.name);
console.log(dog1.play);
//使用cat接口
let cat1:Cat = {
name:'哈士奇',
color:'黑白相间',
//此方法可有可无
// play(){
// console.log('哈士奇,汪汪汪')
// }
}
//调用cat1对象
console.log(cat1.name);
console.log(cat1.color);
// //使用type定义的别名
type animal = {
name:string,
age:number,
play?():void
}
//使用type类型的别名
let an1:animal = {
name:"我是animal type 类型",
age:18,
play() {
console.log('我是animal的play方法');
}
}
//调用an1对象
console.log(an1.name);
console.log(an1.play);
最后编译测试:
最后小结:
类型推论:
介绍:
- 在TS中,在有些没有明确指出类型的地方,类型推论会帮助提供类型。
- 换句话说:由于类型推论的存在,某些地方,类型注解是可以省略不写的。
常见场景:
声明变量并初始化
决定函数返回值时
提示:
如果不知道类型,可以通过鼠标放在变量名称/方法名称上,利用VSCode的提示来查询类型。
定义demo5.ts文件:
代码:
//类型推论
let username ='daoen'
let userAge = 18
console.log(typeof username);
console.log(typeof userAge);
使用vsCode鼠标悬停在,声明的变量中,进行类型推论。
推轮一:
推论二:
编译调用测试: