一、简介
1、TS是什么?
以JS为基础构建的语言,一个JS的超集。
可以在任何支持JS的平台中执行;
TS扩展了JS,并添加了类型;
TS不能被JS解析器直接执行,需要将TS编译为JS;
2、TS增加了什么
增加了类型、支持ES新特性、添加了ES不具备的新特性、配置选项。
二、环境搭建
1、安装Node.js
2、安装TS:npm i -g typescript
3、创建一个TS文件
4、使用TSC对TS文件进行编译:tsc xxx.ts
三、基本类型
1、声明
通过类型声明可以指定TS变量(参数、形参)的类型。
指定类型后,当为变量赋值时,TS编译器会自动检查值是否符合类型声明。
声明方式:let xxx:类型;
let xxx:类型=值;
function fun(参数名1:类型,参数名2:类型):返回类型 { ... }
自动类型判断:当对变量的声明和赋值同时进行时,TS编译器会自动判断变量的类型
如果变量的声明和赋值同时进行,可以省略类型声明。
2、类型
| 类型 | 例子 | 描述 | 
|---|---|---|
| number | 正数、负数、小数 | 任意数字 | 
| String | 'h',"h",gh | 任意字符串 | 
| Boolean | true、false | 布尔值 | 
| 字面量 | 其本身 | 限制变量的值就是改字面量的值 | 
| any | * | 任意类型 | 
| unknown | * | 类型安全的any | 
| void | 空值(undefined) | 没有值或者undefined | 
| never | 没有值 | 不能是任何值 | 
| object | {name:"xxx"} | 任意的JS对象 | 
| array | [1,2,3] | 任意JS数组 | 
| tuple | [6,5] | 元素、TS新增类型,固定长度数组 | 
| enum | enum{A,B} | 枚举,TS中新增类型 | 
字面量
可以给对象赋值一个固定的值,可以通过 | 来赋值多个值或多中类型
|------------------------|-------------------|
| let a:10               | a的值只能是10          |
| let b:10 | "aabc"     | b的值只能是10或者字符串aabc |
| let c:number | string | c的值只能是数字或者字符串     |
any
可以是任何值(一般不用)
把这两个变量赋值给其他变量
两种定义方式:let a:any (显示) let b (隐式)
|-----------|-------------------|
| let a:any | a="1";a=1;a=false |
| let b     | b="1";b=1;b=false |
unknown
可以是任何值(安全的any)。
|---------------|-------------------|
| let a:unkonwn | a="a";a=1;a=false |
any与unknow的区别:
            
            
              TypeScript
              
              
            
          
          let s:string  s="1";
let a:any     a=1;
let b:unknown  b="1";
s=a(不报错)
s=b(报错)强制转换unknown
            
            
              TypeScript
              
              
            
          
          //方式1
if(typeof b==='string'){s=b}
//方式2
s=e as string;void
            
            
              TypeScript
              
              
            
          
          //返回null或者undefined(不用return)
function fu():void{}
//null或者undefined都不返回
function fu():never{ throw new error('报错')}Object
表示一个JS对象;
let a:object; a={}; a=function(){}
{}用来指定对象中可以包含那些属性。
语法:{属性名:属性值,属性名:属性值......属性名(不是必须的)?:属性值}
在属性后面写?,表示这个属性可写可不写。
            
            
              TypeScript
              
              
            
          
          Let b:{name:string}
b={name:"xxxx"}
Let c:{name:string,age?:number}
c={name:"xx"}
c={name:"xxx",age:1}随意数量的属性名:{属性名:值,[变量名:string:any]};
            
            
              TypeScript
              
              
            
          
          //abc代表任意类型的属性
Let b:{name:string,[abc:string]:unknown}
b={name:"xxx",c:"xx",d:false}
b={name:"xxx"}当对象为函数时。其中a、b参数已定义为number所以在function中的参数和返回值
需要定义时的一致,在function中进行显示的定义类型也不行。
            
            
              TypeScript
              
              
            
          
          Let d:(a:number,b:number)=>number;
d=function(n,m){return n+m}Array
声明方式:类型[]、array<类型>
            
            
              TypeScript
              
              
            
          
          Let a:string[];
Let b:number[];
Let c:array<String>Tuple
长度固定的数组。
声明方式:Let xxx:[ 类型1,类型2,...]
Enum
枚举:enum类名{ 变量名=值,变量名=值,.......}
使用:类名.变量名
其他注意
&表示同时
Let a:{name:string}&{age:number};
a中的属性需要name和age同时出现。
类的别名
Type mytype=1 | 2 | 3 | 4;
Let a:mytype;
a的值可以是mytype中的任何值。
四、编译选项
1、自动编译文件
编译文件时,使用-w指令后,TS编译器会自动监视文件中的变化,并在文件发生变化时对文件重新编译。
            
            
              TypeScript
              
              
            
          
          tsc xxx.ts -w2、自动编译整个项目
直接使用TSC命令,可以自动将当前项目下的所有TS文件编译为JS文件。
步骤:在当前目录创建一个tsconfig.json
在这个文件中配置:include、exclude等配置。
include:定义希望被编译文件所在目录。
include:["路径","***"]
**:表示当前路径所有文件、文件路径。
*:表示当前路径所有文件。
exclude:定义需要被排除的文件目录
exclude:["",""]
extend:定义被继承的配置文件。
extend:["",""]
files:指定被编译文件的列表。
files:["xxx.ts","aaa.ts"]
CompilerOptions:编译器的选项,使用JSON配置。
target:编译成JS的版本。
"target":"ES6" (ES3、5、6、2015、16、17、18......)
module:指定要使用的模块化的规范。
"module":"none" (none、system、amd......)
lib:用来指定项目中要使用的库
"lib":"es5" (ES5 ES6 ES2015)
outDir:用来指定编译后文件的所在目录
"outDir":"./dist"
allowJs:是否编译JS,默认否。
"allowJs":false
checkJs:是否检查JS代码,默认false。
"checkJs":false
removeComments:是否移除注释。
"removeComments":false
noEmit:不生成编译后的文件。
"noEmit":true
NoEmitOnError:当生成时有错误。就不生成。
"NoEmitOnError":false
语法检查相关的配置:还是在CompilerOptions下配置。
alwaysStrict:开启严格模式,默认false,当有引入和export操作时默认开启。
"alwaysStrict":false
noImplicitAny:检查隐式的any
"noImplicitAny":true
noImplicitThis:不允许不明确类型的this。
"noImplicitThis":true
strictNullChecks:检查空值,在变量可能为空时报错。
"strictNullChecks":true
strict:严格检查的总开关。开启以上的语法相关检查。
"strict":false
五、面向对象
1、类简介
类就是对象的模型,程序中可以根据类创建指定类型的对象。
创建一个对象:class 对象名{......}
创建一个属性:属性名:类型=值;
创建一个静态属性:static 属性名:类型=值;
创建一个只读属性:readonly 属性名:类型=值;
创建一个只读静态属性:static readonly 属性名:类型=值;
创建一个方法:方法名{...方法体...}
创建一个静态方法:static 方法名{...方法体...}
构造函数:构造函数在对象被创建时调用。
写法:constructor( 属性名:类型,属性名:类型)
{this.属性=属性;this.属性=属性}
this代表当前实例对象。
访问非静态的属性或方法:const xx=new 类名(); xxx.属性 xxx.方法名
访问静态的属性或者方法:类名.属性 类型.方法名
            
            
              TypeScript
              
              
            
          
          class Person{
    name:string;
    age:number=1;
    static a:string="xxx";
    readonly b:string="abc";
    static readonly c:string="ccc";
    printa{
        console.log(this.a)
    }
    static printb{
        console.log(this.b)
    }
}
let person=new Person();
person.name="abc";
person.printa();
Person.c;
Person.printb()2、继承
使用继承后,子类将拥有父类中的所有方法和属性。
通过继承可以将多个类中共有的代码写在同一个父类中。
方法重写:如果在子类中添加了父类相同的方法,则子类方法会覆盖父类的方法。
方式:在子类中的子类名后面使用extends父类名来继承父类。
关键字:super。作用调用父类中的方法。
方式:在子类中使用super.父类方法();
            
            
              TypeScript
              
              
            
          
          class Parent{
    name:string;
    
    constructor(name:string){
        this.name=name;
    }
    publicMethod(){
        console.log('我是父类方法');
    }
}
class ChildOne extends Parent{
    one:string;
    constructor(name:string,one:string){
        super(name);
        this.one=one;
    }
    oneMethod(){
        console.log("子类方法")
    }
}
class ChildTwo extends Parent{
    two:string;
    constructor(name:string,two:string){
        super(name);
        this.two=two;
    }
    publicMethod(){
        console.log("复写了父类的方法")
    }
}3、抽象类
以abstract开头的类是抽象类。
抽象类与其他类区别不大,只是不能用来创建对象。
抽象类就是专门用来继承的类。
抽象类中可以添加抽象方法(没有方法体);
abstract 方法名():返回类型;
            
            
              TypeScript
              
              
            
          
          abstract class Parent{
    name:string;
    constructor(name){
        this.name=name;
    }
    abstract publicMethod():string;
}
class ChildOne extends Parent{
    age:number;
    constructor(name,age){
        super(name);
        this.age=age;
    }
    
    publicMethod(){
        console.log("复写父类中的方法")
    }
}4、接口
作用:规范类的属性、方法等。(零件规格一致才能公用)
接口中可以有属性(没有值)、方法(没有方法体);
实现:interface 接口名{}
子类实现:class 类名 implements 接口{}
            
            
              TypeScript
              
              
            
          
          interface Animal{
    name:string;
    yell():void;
    
}
class Cat implements Animal{
    name:string;
    constructor(name){
        this.name=name
    }
    yell(){
        console.log("喵喵喵")
    }
}5、属性的封装
修饰属性的修饰符
public:修饰的属性可以在任意位置访问修改;
Private:私有属性。只能在本类内部进行访问;通过给类添加方法可以是的私有属性能
被访问。
protected:受保护的属性。只能当前类和当前类的子类可以访问此属性。
            
            
              TypeScript
              
              
            
          
          class Animal{
    public _name:string;
    protected _age:number;
    private _sex:string;
    constructor(name:string,age:number,sex:string){
        this._name = name;
        this._age = age;
        this._sex = sex;
    }
    
    set sex(value:string){
        this._sex = value;
    }
    get sex(){
        return this._sex;
    }
}
class Dog extends Animal{
    public abc:string;
    constructor(name:string,age:number,sex:string,abc:string){
        super(name,age,sex);
        this.abc=abc
    }
}
let dog=new Dog('小黑',2,'男',"xx");
//只能访问下面两个属性
dog._name;
dog.sex;6、泛型
作用:在类型不明确的时候代替类型使用。
方法:在方法、类中使用大写字母代替。
            
            
              TypeScript
              
              
            
          
          function method<T>(a:T):T{
    return a;
}
function method2<A,T>(a:A,b:T):T{
    return b;
}
class Person<T>{
    name:T;
    constructor( name:T){
        this.name = name
    }
}
method(1)
method<string>("1")
let perosn=new Person<string>('zhangsan')