美文网首页
TypeScript的基础认识

TypeScript的基础认识

作者: 墨尘_7 | 来源:发表于2018-12-12 15:22 被阅读0次

    原始数据类型

    booleannumberstringnullundefinedSymbol

    //空值的概念 void
    function alertName(): void {
       alert('My name is Tom');
    }//表示没有任何的返回值
    let unusable: void = undefined;//当数据类型是void时,其值只能为undefined/null
    
    TypeScriipt存在类型推论

    1.在赋值的时候要添加类型

    let num: string = 'seven';     正确写法
    或者
    let num: string | number;     正确写法
    

    2.在赋值的时候不添加类型,但赋初值

    let num = 'seven';   会提示错误,但会推论为string类型
    

    3.在赋值的时候不添加类型,也不赋初值

    //任意值 Any
    let num;   会提示错误,类型推论为任意值 Any,可以正常给运行
    num = 'seven';
    num = 7;
    

    接口 interface(对象的类型)

    1、常规接口

    //定义对象的类型
    interface num{
       name: string;     //确定属性
       age: number;     //确定属性
    }
    //给who一个num的接口,并赋值(必须要和完全一致不能多也不能少)
    let who: num= {
       name: 'bom',
       age: 17
    };
    

    2、可选属性和任意属性

    //可选属性
    interface num{
       name: string;     //确定属性
       age: number;     //确定属性
       sex?: string;     //可选属性
    }
    //给who一个num的接口,并赋值(必须要和完全一致不能多也不能少),可选属性可有可无
    let who: num= {
       name: 'bom',
       age: 17
    };
    
    //任意属性
    interface num{
       name: string;
       age: number;
       [propName: string]: any;     //任意属性
    }
    //给who一个num的接口,基本属性完全制止,此外可以添加任何属性
    let who: num= {
       name: 'bom',
       age: 17,
       sex: 'boy'
    };
    
    • !!!要注意的是一旦设置任意属性确定属性可选属性必须是任意属性的子属性,例如
    //任意属性
    interface num{
       name: string;
       age: number;
       [propName: string]: string;     //任意属性的类型为string,而age为number,编译的时候就会报错
    }
    let who: num= {
       name: 'bom',
       age: 17,
       sex: 'boy'
    };
    

    3、只读属性 readonly

    //只读属性
    interface num{
       readonly id: number;   //在第一次给num对象赋值后,不能被更改的属性
       name: string;
       age: number;
    }
    let who: num= {
       id: 777,
       name: 'bom',
       age: 17,
    };
    who.name = "mom"   //不会报错
    who.id = 666;    //这里就会报错
    

    数组的类型

    let num: number[] = [1, 2, 2, 3, 5];    统一类型的数组
    let num: Array<number> = [1, 2, 2, 3, 5];    统一类型的数组,泛型
    let num: any[] = ['Mo chen', 23, { web: 'https://?????.com' }];   可以出现任意类型的数组
    
     用接口的形式表示数组
    interface NumberArray {
       [index: number]: number;
    }
    let num: NumberArray = [1, 2, 2, 3, 5];
    

    函数的类型

    1.函数的输入和输出要做类型约束

    function num(a: number, b: number): number {
       return a+ b;
    };   
    

    2.使用接口做为函数的约束

    interface num {
       (a: string, b: string): boolean;
    }
    let myNum: num;
    myNum= function(a: string, b: string) {
       return a+b === -1;
    }
    
    • 函数的类型a: number是必须要写的; c?: number为可选; 可选参数必须接在必需参数后面!!!!
    function num(a: number, b: number,c?: number): number {
       return a + b + c;
    };   
    

    3.参数默认值

    function num(a: number=2, b: number): number {
       return a+ b;
    };   
    console.log(num(undefined,2))   //4 ,也可以给a值,就会覆盖默认值
    

    4.剩余参数(rest 参数)

    function push(array, ...items) {
       items.forEach(function(item) {
           array.push(item);
       });
    }
    
    let a = [];
    push(a, 1, 2, 3);   这里调用push的时候,第一个参数就代表array,其余后面的参数就是items命名的数组
    

    5.重载
    .....

    类型断言

    function num(a: string | number): number {
       if ((<string>a).length) {
           return (<string>a).length;
       } else {
           return a.toString().length;
       }
    }
    

    简而言之 就是在需要断言的变量前面加<type>

    声明文件(当使用第三方库的时候)

    //JavaScript使用方法
    $("#key1")
    //或者
    jquery("#key2")
    
    //TypeScript使用方法
    declare var jQuery: (selector: string) => any;//在 TypeScript 中不知道 $ 或 jQuery 是什么,需要使用 >declare 关键字来定义它的类型
    jQuery('#foo');
    //或者
    declare var $: (selector: string) => any;
    $('#foo');
    

    可以使用 @types 来管理声明,例如Jquery

    npm install @types/jquery --save-dev
    

    在xxx.ts的文件头部将Jquery引入

    import $ = require("jquery");
    

    内置对象

    1.ECMAScript 的内置对象: Boolean、Error、Date、RegExp 等

    let b: Boolean = new Boolean(1);
    let e: Error = new Error('Error occurred');
    let d: Date = new Date();
    let r: RegExp = /[a-z]/;
    

    2.DOM 和 BOM 的内置对象: Document、HTMLElement、Event、NodeList 等

    let body: HTMLElement = document.body;
    let allDiv: NodeList = document.querySelectorAll('div');
    document.addEventListener('click', function(e: MouseEvent) {
     // Do something
    });
    

    3.TypeScript 核心库的定义文件
    ....

    TypeScript实用方法

    类型别名(使用 type 创建类型别名)
    type Name = string;
    type NameResolver = () => string;
    type NameOrResolver = Name | NameResolver;
    function getName(n: NameOrResolver): Name {
       if (typeof n === 'string') {
           return n;
       } else {
           return n();
       }
    }
    
    字符串字面量类型(使用 type 创建类型别名)
    type EventNames = 'click' | 'scroll' | 'mousemove';
    function handleEvent(ele: Element, event: EventNames) {
       // do something
    }
    
    handleEvent(document.getElementById('hello'), 'scroll');  // 没问题
    handleEvent(document.getElementById('world'), 'dbclick'); // 报错,event 不能为 'dbclick'
    
    元组

    ....

    枚举

    使用enum定义;如:enum Days {Sun, Mon, Tue, Wed, Thu, Fri, Sat}

    • 普通枚举(常数项 和 计算所得项)enum
    • 常数枚举 const enum
    • 外部枚举 declare enum

    类(万分重要的东西!!!)

    1. 类(Class) :定义了一件事物抽象的特点,包含了属性和方法
    2. 对象(Object):类的实例,通过 new 生成
    3. 面向对象(OOP)的三大特性:封装、继承、多态
    • 封装(Encapsulation):将对数据的操作细节隐藏起来,只暴露对外的接口。外界调用端不需要(也不可能)知道细节,就能通过对外提供的接口来访问该对象,同时也保证了外界无法任意更改对象内部的数据
    • 继承(Inheritance):子类继承父类,子类除了拥有父类的所有特性外,还有一些更具体的特性
    • 多态(Polymorphism):由继承而产生了相关的不同的类,对同一个方法可以有不同的响应。比如 Cat 和 Dog 都继承自 Animal,但是分别实现了自己的 eat 方法。此时针对某一个实例,我们无需了解它是 Cat 还是 Dog,就可以直接调用 eat 方法,程序会自动判断出来应该如何执行 eat
    1. 存取器(getter & setter):用以改变属性的读取和赋值行为
    2. 修饰符(Modifiers):修饰符是一些关键字,用于限定成员或类型的性质。比如 public 表示公有属性或方法
    3. 抽象类(Abstract Class):抽象类是供其他类继承的基类,抽象类不允许被实例化。抽象类中的抽象方法必须在子类中被实现
    4. 接口(Interfaces):不同类之间公有的属性或方法,可以抽象成一个接口。接口可以被类实现(implements)。一个类只能继承自另一个类,但是可以实现多个接口
    class Num {
       constructor(data) {       constructor定义构造函数
           this.data = data;
       }
       myData() {
           return `My data is ${this.data}`;
       }
    }
    let b = new Num('number');
    console.log(a.myData());       // My data is number
    
    类的继承

    extends继承,super调用父类的方法和属性

    class NumChild extends Num {
       constructor(data) {
           super(data);   // 调用父类的 constructor(data)
           console.log(this.data);
       }
       myData() {
           return 'Ho!, ' + super.myData(); // 调用父类的 myData()
       }
    }
    
    let c = new NumChild('number2'); // number2
    console.log(c.myData()); // Ho!, My data is number2
    
    存储器

    使用getset改变属性的赋值和读取行为

    class Num {
       constructor(data) {
           this.data = data;
       }
       get data() {
           return 'number';
       }
       set data(value) {
           console.log('data: ' + value);
       }
    }
    
    let a = new Num('One'); // data: One
    a.data = 'Tow'; // data: Tow
    console.log(a.data); // number
    
    静态方法

    使用static修饰符修饰方法要直接在类上使用,实例化后不能被使用

    class Num {
       static isNum(a) {
           return a instanceof num;
       }
    }
    Num.isNum(a); // true
    let a = new Num('mom');
    a.isAnimal(a); // TypeError: a.isAnimal is not a function
    
    ES7

    可以在类里面直接定义属性

    class Animal {
       name = 'Jack';
    
       constructor() {
           // ...
       }
    }
    
    let a = new Animal();
    console.log(a.name); // Jack
    

    可以静态属性

    class Animal {
       static num = 42;
    
       constructor() {
           // ...
       }
    }
    
    console.log(Animal.num); // 42
    
    public private 和 protected
    • 三种访问修饰符public(公有)、private(私有) 和 protected(受保护,与private类似只是它的子类是可以访问的)
    抽象类

    abstract定义抽象类和其中的抽象方法(抽象类不允许被实例化)

    abstract class Animal {      这就是被abstract定义的抽象类,当它被实例化的时候会报错
       public name;
       public constructor(name) {
           this.name = name;
       }
       public abstract sayHi();     其次就是被抽象类定义的抽象方法,必须在子类中实现,不然也会报错
    }
    
    类的类型

    和接口的类型定义比较类似

    class Animal {
       name: string;
       constructor(name: string) {
           this.name = name;
       }
       sayHi(): string {
         return `My name is ${this.name}`;
       }
    }
    

    类实现接口

    implements来实现接口对接
    为什么要有接口?就是多个类共有的特性提取成特性方便使用

    interface Alarm {      第一个接口
       alert();
    }
    
    interface Light {        第二个接口
       lightOn();
       lightOff();
    }
    
    class Door {            类
    }
    
    class SecurityDoor extends Door implements Alarm,Light {       类继承类对接接口
       alert() {
           console.log('SecurityDoor alert');
       }
       lightOn() {
           console.log('Car light on');
       }
       lightOff() {
           console.log('Car light off');
       }
    }
    
    class Car implements Alarm {                     类对接口
       alert() {
           console.log('Car alert');
       }
    }
    

    接口与接口之间有继承关系(extends)

    interface Alarm {
       alert();
    }
    
    interface LightableAlarm extends Alarm {
       lightOn();
       lightOff();
    }
    

    接口继承类....
    混合类型....

    声明合并

    *以上是个人总结,希望能对大家有所帮助。更详细更具体的可以参考TypeScript 入门教程

    相关文章

      网友评论

          本文标题:TypeScript的基础认识

          本文链接:https://www.haomeiwen.com/subject/yuqshqtx.html