TypeScript笔记

216 阅读9分钟

TypeScript前期准备:

需要安装 node  npm  
ios安装node指令 brow install nodejs 
还需要安装homebrew

TypeScript

面向对象语法(Prototype,Function,Object)
class interface自己实现了类接口
类型检查(静态 ,强类型)

TypeScript 优点

1.面向对象
2.类型检查 更好避免bug
3.自带文档特性
4.IDE或编辑工具良好支持(自动提示在 做大项目代码量多的时候很方便)
5.自动编译时能提前发现错误
TypeScript = TypeScript  + type +(some other stuff)主要是类型不同
TypeScript 需要编译成JavaScript

编译指令:

tsc + 文件名.js

类型的定义

三种定义类型方法=>   var     let     const
var :函数级作用域(怎么理解  例子如下):
        if(true){var i = 1;}
          console.log(i)   可以输出 i = 1
        if(true){let i = 1;}
          console.log(i)   直接报错 let找不到i
let:限制变量的作用范围
const:定义常量
其中var可重复定义   let 不可以重复定义   定义好的类型都不可以改变 
   
例如:var a : number;
                     a="hello"     直接报错

定义数组的两种方法:

1.let myArr : number [] = [1,2,3]
2.let myArr : Array<boolean>=[false,false,true];

元组 yuple

跟数组差不多 但是里面的元素可以多个类型
编译出来的JavaScript也是数组
元素个数是固定的   顺序不能变
定义元组  
let my_tuple:[string,number]=['abc',123]

箭头函数

const add = (a:number,b:number) =>{
    return a+b;
}
let sum = add(10,20);
    console.log(sum); 
等同于:
function add (a:number,b:number){
    return a+b;
}

返回值类型

const add = (a:number,b:number):number//(此处规定函数返回值类型) =>{
    return a+b;
}
let sum = add(10,20);
console.log(sum.toFixed(2));//保留两位小数 编译后=30.00

const add = (a:number,b:number):String=>{
    return a.toString()+b.toString();
}
let sum = add(10,20);
console.log(sum.substr(0,3));//编译结果为102,截取3个字符串长度

函数指定返回值的类型

可以让调用的地方知道是什么类型的返回值,以便进行处理

默认参数(=)
可选参数(?) //赋值方式一般放到参数后面,默认的参数可以不指定类型,会自动判断和计算

any的使用

let a :any;//可以为任意类型
    a = 10 ;
    a = "abcd";
    a = [1,2];

const log = (value:any)=>{
    if(typeof value === 'number'){
       return 'your name is ${value}';
      }
    if(typeof value === 'String'){
       return 'your name is ${value}';
      }
    therow new Error('Expected String or number ,got ${value};')
};
    console.log(log('abc')); //输出   your name is abc
    console.log(log(123));   //输出   your name is 123
    console.log(log([1,2])); //输出   设定的异常

typescript的写法

    function isNumeber(value:any):value is number{
       return typeof value === "number";
}
    function isNumeber(value:any):value is String{
       return typeof value === "String";
}

undefined 和 null 有自己的类型为 undefind和null,默认情况是所有类的子集
如果编译时指令为 tsc --strictNullchecks index.js 会报错,默认的情况就失去效果

类Class

class (模板) new 对象
数 据 (data) 行为 (action)
行为可能是对数据进行操作
//模板
Class Person{
    //定义两个数据内容
    firstName:String;
    lastName : String;
}
//生成一个对象
let aPerson = new Person();
//设置firstName的内容
aPerson.firstName = "hello"
//读取firstName的内容
console.log(aPerson.firstName);
编译后输出:hello
}

//例子
Class Movies{
    name:String;
    play_count:number;
    created_at:String;
    time:String;
}
let m = new Movies();
m.name = "这是一个例子"
console.log(m.name);
编译后输出:这是一个例子
}

面向对象概念

                                  Class 模板
                                /     |     \
                               /      |      \
                              /       |       \
                             /        |        \
                     真实Object  真实Object   真实Object
                          |           |           
                          |           |           
                      宝马(车)       奥迪(车)
                        class         class

//例子代码
Class Person{
//定义了两个数据内容
    firstName:String;
    lastName : String;
great(){
    console.log('hi');
}
othergreet(){
    this.greet();
console.log('*****');
    }
}
//继承了父类的数据和行为,就是属性和方法
//他的父类是Person

Class Programmer extends Person{
    greet(){
    console.log('hello world');
}
//super代表父类
greetLikeNormalPeople(){
    super.greet();
    }
}
let aPregrammer:Preson = new Programmer();
//let aPregrammer:Programmer = new Programmer();
    调用方法时,先找本身对象的方法,如果没有,会找父类的方法
    aProgrammer.greet();
    aProgrammer.greetLikeNormalPeople();
    aProgrammer.othergreet();
//生成一个对象
let aPerson = new Person();
设置firstName内容
    aPerson.firstName = "hello";
    aPerson.othergreet();
//读取firstName的内容
console.log(aPerson.firstName);
}

三个修饰符对成员属性和方法进行修饰

    public 公有的 任何属性和方法都可以在生成的对象中调用,继承的对象也能调用  默认是public
    
    private 私有的 只有在内部对象内才能访问,生成的对象调用不了,要调用的私有方法和属性可以在class里
定义public的方法来调用
    继承的对象也是不能够直接用生成的对象来访问
    子类继承的时候也可以继承私有属性和方法 也是要通过继承过来的public方法来调用

    protected 受保护的,只有在内部class还有子类能访问 生成对象访问不了 要调用私有方法和属性 可以在class里定义
public的方法来调用
    继承的对象也是不能够直接用生成的对象来访问
    子类继承的时候也可以继承私有属性和方法 也是要通过继承过来的public方法和自己定义的public方法在外部调用
    (这点和其他语言有些不一样)
    
    内部调用:class里面的方法
    外部调用:生成对象的时候

private protected 区别 在子类的时候
    1.继承方法一样的表现形式 可以内部访问继承过来的public private protected 属性和方法
    2.子类定义的方法 只能通过访问继承过来的public和protected的属性和方法 不能访问继承过来的private属性和方法
如果要访问父类的private属性和方法 可以通过继承过来的public private protected方法在内部访问
//代码例子
Class Person{
    private firstName:String;
getfirstName(){
    console.log(this.firstName);//暴露一个方法
    }
setfirstName(firstName){
    this.firstName = firstName;
    }
}
let aPerson = new Person();
    aPerson.setfirstName('abc');
    aPerson.getfirstName();
编译后结果为:abc
或
private SayHi(){
    console.log('abcd'); 
}
public CallSayHi(){
    this.SayHi();
    console.log('1234'); 
}
aPerson.CallSayHi();
编译输出结果为:abcd1234

构造方法constructor

如果声明为protected 或private 当前类不能new
当父类声明为protected 子类重写constructor方法可以new(子类可以new)
如果父类声明为private子类不能new和extends
super()在constructor方法中是调用父类的构造方法,必要时要传入参数

作用

1.当不想被实例化,而只想让子类继承后实例化 可以声明为protected
2.都不想让子类和父类实例化或继承可以声明为private
3.一般情况下声明为public(或不写)

静态属性和方法 static

通过类似Person加方法名或属性来调用(比如Person.age)
默认是声明为public
如果是protected 或private的话 当前类都不能调用,通过public的静态方法来调用
如果父类是protected 或private的话 子类也能继承所有的静态方法和属性
子类还是不能调用protected 或private的方法和属性只能通过继承的public的方法来调用
子类定义的方法(public)只有是父类定义为public或protected的才能访问,private的不能访问

Readonly 只读属性

    readonly name :String = 'abc'
    只读属性,不能修改相当于常量

枚举类型

enum DaysofTheWeek{
    SUN,MON,TUE,WED,THU,FRT,SAT
}
let day : DaysofTheWeek;
day =  DaysofTheWeek.MON;
    console.log(day); 
编译输出:1
如果给一个默认值例如SUM=100,那么就变成从100开始

enum:
它的值是数字序列,从0开始
代码可读性强
用于下拉框等应用

Ts-node nodemon

Ts-node 直接执行ts格式文件
安装指令:npm install -g ts-node   全局安装
使用格式:ts-node script.js

nodemon 监控js文件改变,自动运行
安装指令:npm install -g nodemon   全局安装
使用格式:nodemon --exec ts-node./index.js

接口interface

    接口规定了如何设计 就是一些规范
    电脑上的usb接口 如果要实现鼠标 u盘等不同的电器都可以接入在
设计时必须按照usb接口来设计
    和java一样 都是为了解决类的单继承问题

类实现接口

代码示例如下:

//支付接口 实现接口 微信支付 支付宝支付
interface Pay{
    post():void;
}
//可能会发送http请求 真正支付的请求
const do_Pay=(Pay:pay)=>{
    pay.post()
}
//微信支付
class WePay inplement pay{
//调用微信支付的接口
    post(){}
}
//支付宝支付
class AliPay implement pay{
//调用支付宝的接口
    post(){}
}
//其他支付接口
let we_Pay:pay=new WePay();
let ali_Pay:pay=new AliPay();
//微信支付  取值
do_Pay(We_Pay);     
//支付宝支付 取值
do_Pay(Ali_Pay);

下列代码可理解为匿名函数

interface PrintCallback{
    (success=boolean):void
}
let PrintCallback:PrintCallback;
PrintCallback=(suc:boolean):void=>{}

类型断言

在typescript中类型断言是告诉编译器变量是哪个类型的方式
跟类型转换有点类似 但只用于编译时期
类型转换是在运行时期强制转化类型

示例:
//x代表可以是任何类型比如字符串number之类的
//编译器可能不能明确知道x是那种类型
let x :any="111";
//<String>表示把x断言成字符串类型就是告诉编译器要把x当成字符串 才有这个函数
let s =(<number>x);
console.log(typeof s);

示例代码如下:
inter Person{
    name:String;
    age:number:
}
//一种写法
let Person1 = <Person>{
    name="abc";
    age=27;
}
//另一种写法
let Person ={} as Person;   //这里的as 更好的明确类型和类型里面的结构
Person.name="abc";
Person.age=27;

接口继承

class ComPonent{
    private width : number;
    private height : number;
Constructor(width : number,height : number){
    this.width=width;
    this.height=height;
}
display():void{
    console.log(this.height);
 }
}
接口继承类
继承类的方法和属性 但可以不用实现方法
也可以定义自己的方法和属性
interface widget extends Component{
    hide():void;
}
class Button extends component implements widget{
    hide():void{
    console.log('hiding');
 }
}
let w:widget=new Button(1,2);
    console.log(w);
    w.display();
    w.hide();
indexable.Types语法:       索引性类型
    [propName:String]:any 
interface states{
    [index:string]:boolean;
          这是key值     key可以是数字  字符串
let s:states={
    'enabled':true,'maximized':fase
 }
}

interface states1 {
    [index:number]:boolean; 这种方式定义的数组没有push length join 
                            等属性和方法有局限性
let s1:states1=[true,fase,true];
let s2:number[]=[1,2,3]     这种方式定义的数组可以正常使用push length join
                            索引参数一定是string或mnumber
                            let s2:后面的
                            string等于对象
                            number等于数组 
}

处理数组列表结构

根据                               
let todos = [
  {
    "userId":1,
    "id":1,
    "title":"abc",
    "completed":fase
  }
]                              
...数组2,
...数组3,
可以这样写
interface Todo{
  {
    "userId":number,
    "id":number,
    "title":"string",
    "completed":boolean
  }
}

let todos 改成
let todos:Todo[]:{
...数组,
}

抽象类

abstract class person{
    name:String;            //不能实例化
constructor(name:String){
    this.name=name;
 }
display():void{
    console.log(this.name);
 }
}
Class Employee extends Person{
    name:String;
    empcode:number;
constructor(name:String,code:number){
    super();               //必须调用super
this.name=name;
this.empcode=code;
 }
//必须实现抽象的方法
find(name:String):person{
    return new Employee(name:())
 }
} 

Accessors

class Person{
    private _name:String;
    private _age:number;
constructor(name:String,age:number){
    this._name=name;
    this._age=age:
}
//读取
getName():String{
    return this._name;
}
//设置
setName(name:String):void{
    this._name=name;
}
get name():String{
    return this._name;
}
set name(name:String){
    this._name=name;
 }
}

let p :Person = new Person("abc",29);
//输出name
console.log(p.name);
//修改name
p.mame="test";
console.log(p);