TS基础教程
一、安装
-
打开终端,输入
npm install typecript -g
如果报错
- 清空缓存:
npm cache clean --force
- 提权下载:
sudo npm install typescript -g
- 清空缓存:
-
查看下载版本号:
tsc -v
-
运行ts
ts运行有两种方式。一是通过tsc编译成js文件,再通过node直接js文件。第二种就是通过ts-node直接运行ts文件。这里我们采取第二种ts-node
sudo npm install @types/node -g
Sudo npm install ts-node -g
之后我们就可以直接在终端使用:ts-node 文件名.ts 命令运行ts文件
二、基础类型
1. string字符串
使用string表示,通过‘单引号’或者“双引号”进行赋值
let username:string = "ny name is songzi."
console.log(username)
模板语法:字符串也可以使用模板语法进行赋值,引用模板变量的与被引用的变量都需要以``符号包括,格式是${变量名称}
let username:string = `songzi`
let introduce:string = `my name is ${username}`
// my name is songzi
2. number数字
使用number表示,可以初始化为NAN、普通数字或者infinity无穷大
let age:number = NaN // 空值
let age:number = 22 // 普通数字
let age:number = Infinity //无穷大
3. list数组
使用list表示,可以设置空列表或者初始化传值,也可以进行下标获取、循环获取、列表拼接、排序等
let testlist:number[] = [] //定义空列表
let testlist:number[] = [1,2,3] // 列表初始化传值
console.log(testlist[0]) //获取指定下标(从0开始)
// 循环获取列表
var i;
for (i in testlist){
console.log(testlist[i])
}
4. map对象
5. tuple元祖
元祖通常是在已知元素的数量、类型情况下使用,你也可以当做是一个约束。以下mytuple就表示,该元素类型只能为2个,且第一个的类型必须为string,第二个的类型必须为number,否则会显示错误
let mytuple: [string, number];
mytuple = ['songzi', 22] // true
mytuple = [100, 22] //false
6. Boolean布尔值
通过boolean表示,只有TRUE、FALSE两个值。但是不可以赋值构造函数Boolean,因为此函数返回的是布尔对象。除非把类型:boolean
改为:Boolean
let isexist:boolean = true // 直接设置值
let isexist:boolean = 1 > 2 // 通过返回值来设置值
let isexist:Boolean = new Boolean(1) //构造函数,前提是变量类型需要为Boolean类型。返回值为[Boolean: true]
7. void空值
void表示不会返回任何的值,通常用在函数里面。如果函数的返回值设置为了void,那么return任何值都是会报错的
// 用作函数返回值
function getName(username:string):void{
console.log(`my name is ${username}`)
}
getName(`songzi`)
// 错误
function getName(username:string):void{
return `my name is ${username}`
}
getName(`songzi`)
void除了在函数返回值中使用,只可以赋值为undefined、null
8. undefined、null
undefined、null是所有类型的子类,意味着,你申明一个任何的数据类型,值都可以等于 undefined或者null。但是需要注意的是,如果你开启了严格模式,那么 undefined、null只能赋值给void或者其本身,如果一定要给其他类型赋值,可以使用联合类型
// 赋值给所有类型
let username:string = undefined
let age:number = null
// 严格模式下
let username:string | undefined = undefined
let age:number | null = null
9. any任意值
顾名思义,这个表示变量类型可以为任意值。并且不会限制其值的修改类型。但是ts也不会为此进行类型的检查,而是直接到编译阶段。
let username:any = "songzi"
username = 123 //true
username = true //true
10. 其他类型
- enum枚举
- 联合类型
三、变量
1. var
函数变量(不推荐使用)
- 变量提升:如果没有在函数内定义那么就升级为全局变量。可以直接通过windows.变量名称直接访问
- 重复定义:如果重复定义不会报错,而是会覆盖。
- 无暂时性死区:在定义之前访问不会报错,值为undefined
2. let
块级元素(推荐使用)
- 块级元素:只有在声明内部与for循环内部才可以访问
- 不可重复定义:如果重复定义会引起报错
- 暂时性死区:与Vue不同,let在声明前调用会报错。直到声明变量的那一行
- 无变量提升:就算是在函数外定义,也不会升级为系统变量,不可通过Window.变量名访问
3. Const
功能与let相似,除了不可修改(尽量使用)
- 不可修改:赋值以后不可修改,所以一般用于常量。
四、运算符
1. 三元运算符
三元运算符一般用来做逻辑判断,减少if else的逻辑判断。格式为:
test ? expr1 : expr2
test为表达式,结果是一个布尔值。将会根据布尔值决定整个表达式的值是哪个。
test为true时,值为expr1
test为false时,值为expr2
示例:
const age:number = 18;
const layer = age > 18 ? men : boy
// 问号?前面的表达式为true时,变量为第一个值,反之为false
2. 类型运算符
-
typeof:查看基础类型,返回值为类型值
// 查看类型 const username:string = "songzi" console.log(typeof username) //string const age:number = 22 console.log(typeof age) //number
-
Instanceof:判断方法或者接口类型
let Car = function() {} let benz = new Car() console.log(benz instanceof Car) // true
五、条件判断
1. If …else …
根据判断条件,决定执行的语句模块。遇到匹配的条件以后,剩下的语句将不会执行
const age:number = 80
if (age < 18){
console.log("未成年")
}else if(age >= 18 && age < 40){
console.log("成年人")
}else if(age >= 40 && age < 60){
console.log("中年人")
}else{
console.log("老年人")
}
2. Switch … case …
- 作用:与if … else … 相同,但是只能比对固定的值,不像if可以做区间判断
- 语句:Switch用作条件语句,case作为判断条件。case必须作为常量,而且类型要与Switch里面判断的为同一个类型
- break:不是每个case都需要break,但是没有break,那case捕捉到以后,还是会继续执行之后的case,直到遇到break语句。
// 不加break,将会执行所有的case
const male:string = "men"
switch (male){
case "men":
console.log("男人")
case "female":
console.log("女人")
}
// 男人 女人
- default:每个Switch语句都可以在结尾加一个default case,当前面所有的case都不符合的时候,将会执行本语句。(类型if判断里面最后的else)
const male:string = "other"
switch (male){
case "men":
console.log("男人")
case "female":
console.log("女人")
default:
console.log("第三方性别")
}
// 三方性别
正常例子
const male:string = "men"
switch (male){
case "men":
console.log("男人")
break
case "female":
console.log("女人")
break
default:
console.log("第三方性别")
}
六、语句循环
1. for循环
- for:一共三个语句,语句1是循环开始前执行 语句2是循环的条件 语句3是每次循环以后执行
let a:any[] = [1, "songzi",true, 4 - 2]
for (var i=0; i < a.length; i++){
console.log(a[i])
}
/*1
songzi
true
2*/
- for … in :直接循环,通过下标取值
let a:any[] = [1, "songzi",true, 4 - 2]
for (var i in a){
console.log("数组下标:",i,"数组的值:",a[i])
}
/*
数组下标: 0 数组的值: 1
数组下标: 1 数组的值: songzi
数组下标: 2 数组的值: true
数组下标: 3 数组的值: 2
*/
- for … of:直接循环,可直接取值
let a:any[] = [1, "songzi",true, 4 - 2]
for (var i of a){
console.log("数组的值:",i)
}
/*
数组的值: 1
数组的值: songzi
数组的值: true
数组的值: 2
*/
- forEach:直接循环,但是可以获取值,下标,原循环对象
let a:any[] = [1, "songzi",true, 4 - 2]
a.forEach((value,index,array) => {
console.log("值:",value,",下标",index,",原数组",array)
});
/*
值: 1 ,下标 0 ,原数组 [ 1, 'songzi', true, 2 ]
值: songzi ,下标 1 ,原数组 [ 1, 'songzi', true, 2 ]
值: true ,下标 2 ,原数组 [ 1, 'songzi', true, 2 ]
值: 2 ,下标 3 ,原数组 [ 1, 'songzi', true, 2 ]
*/
2. while循环
- while
let testnum:number = 10
while(testnum > 0){
console.log("值:",testnum)
testnum--
}
/*
值: 10
值: 9
值: 8
值: 7
值: 6
值: 5
值: 4
值: 3
值: 2
值: 1 */
- do … while:与while区别在于while是先判断条件,再进行循环。而do while先执行语句再判断条件。这意味着即使不符合条件,do while至少也会执行一遍。
let testnum:number = 0
do {
console.log("值:",testnum)
testnum--
}
while(testnum > 0)
// 值: 0
TS高级教程
1、function函数
函数
为了全面展示函数,下面我定义了一个较为复杂的函数,基本函数该有的元素都在里面。
- 定义函数:function student (){}, student便是函数名称
- 参数:参数写在函数名后面的()里面
name:string
——必填参数:并且类型必须是string类型,否则将会引起错误age?:number
——可选参数:表示可以不填。如果填入类型必须为numbermale:string = 'men'
——默认参数:如果不填此参数,此参数的值便取默认值men。相当于设置了一个默认值...info:string[]
——剩余参数:如果我们不知道有多少个参数,并且也不确定类型。我们就可以使用剩余参数。只需要在参数前面加三个点…,此参数是将剩余参数都转换为字符串的数组
- 返回值:
:string
返回值决定了函数返回的数据类型,可不填(函数将会自动判断返回值类型)
function student(name:string,age?:number,male:string = 'men',...info:string[]):string{
return name + age
}
// 调用函数
const stu = student("songzi",22)
console.log(stu) //songzi22
匿名函数
匿名函数定义比较简单,直接将函数赋值给一个变量。除了定义函数的方式不一样,其他的跟函数没有任何区别。
const stu = function (name:string,age?:number,male:string = 'men',...info:string[]):string{
return name + age
}
// 调用函数
console.log(stu("songzi",22)) //songzi22
lambda函数
lambda可以看做是缩减版的函数,声明方法为:变量 = (参数)=> { 函数内容 }
const stu = (name:string,age?:number)=>{
console.log(name + age)
}
stu('songzi',22)
2、interface接口
interface一般声明一些抽象方法,第三方通过具体的类调用这些抽象方法
- 必填类型:变量名称 : 变量类型
- 可选类型:在变量后面加?
// interface接口
interface Message {
firstname: string;
lastname: string;
age:number;
male:male;
phone?:number
}
let stu:Message = {
firstname: "zi",
lastname : "song",
age: 22,
male: male.女性,
}
console.log(stu) //{ firstname: 'zi', lastname: 'song', age: 22, male: 1 }
-
接口单继承
顾名思义,就是一个接口继承了另一个接口。通过
extends
实现
// interface接口
interface Name {
firstname: string;
lastname: string;
}
// 继承接口
interface Message extends Name {
age:number;
male:male;
phone?:number
}
let stu:Message = {
firstname: "zi",
lastname : "song",
age: 22,
male: male.女性,
}
console.log(stu) //{ firstname: 'zi', lastname: 'song', age: 22, male: 1 }
-
接口多继承
interface 不仅仅可以继承一个接口,还可以继承多个
interface Name {
firstname: string;
lastname: string;
}
interface Message {
age:number;
male:male;
}
// 继承多个接口
interface Info extends Name,Message {
phone?:number
}
let stu:Info = {
firstname: "zi",
lastname : "song",
age: 22,
male: male.女性,
}
console.log(stu) //{ firstname: 'zi', lastname: 'song', age: 22, male: 1 }
3、class类
组成:
- 字段:在类里面声明的变量
- 构造函数:在类实例化时候执行
- 方法:可以看做类里面的函数
// 创建类
class Student {
name: string
// 构造函数:会在类被实例化的时候被自动调用
constructor(name: string){
this.name = name
}
testfc():void{
console.log("学生姓名为:",this.name)
}
}
// 实例化类
const stu = new Student("songzi")
// 访问类字段
console.log(stu.name) //songzi
// 调用类方法
stu.testfc() // 学生姓名为: songzi
继承:
- ts中,class类可以继承另一个存在的类。比如现在有一个Animal类,我们还创建一个叫Cat的类。继承Animal。那么Animal就称之为父类,Cat类则为子类。
- 子类通过
extends
继承,除了父类的私有成员(属性、方法)和构造函数,其他的都可以继承 - 跟接口不同,类不能同时继承多个父类。但是可以链式继承,比如A继承了B,而B继承了C。
- 重写:子类继承父类以后,可以重写父类的方法。通过
super
实现。super
可以直接引用父类的属性与方法。
// 创建类
class Student {
name: string
// 构造函数:会在类被实例化的时候被自动调用
constructor(name: string){
this.name = name
}
testfc():void{
console.log("父类方法:学生姓名为:",this.name)
}
}
// 继承student类
class Child extends Student {
testfc(): void {
// 获取父类的函数
super.testfc
// 直接继承父类的属性name
console.log("子类方法:学生姓名为:",this.name)
}
}
const stu = new Child("songzi")
stu.testfc() //子类方法:学生姓名为: songzi
static关键字
static关键词作用在于:不需要对类进行实例化,可以直接获取类属性与方法。
// 创建类
class Student {
static username: string
static testfc():void{
console.log("学生姓名为:",Student.username)
}
}
// 直接调用属性和方法
Student.username = "songzi"
Student.testfc() //学生姓名为: songzi
类的访问控制
该作用是通过修饰符,来控制对类、方法、属性、构造函数的访问。ts提供了三种方法,默认是public
public
:公开,所有的地方都可以访问protected
:受保护的,可以被自身与子类访问private
:私有的,只能在自己类里面被访问