TypeScript学习总结

TypeScript学习总结

可以将其理解为js的一个超集,加入了变量类型检测功能(js是弱类型语言),同时兼容所有的js语法。

安装

我用的是cnpm全局安装,npm太慢会卡死。

npm install -g typescript

成功后测试下

tsc -v
Version 3.8.3

应用

  1. 联合类型检测

在本地创建一个test.ts文件,写上代码

var arr: Array | Array;
arr = [1, 2, 3];
arr = ["1", "2", "3"];

对变量arr做联合类型检测,允许其为元素均为数字或字符串的数组。
然后在命令行输入

tsc test.ts

我们就看到在同目录下转译出了一个js文件test.js。打开看一下,代码被转换成了

var arr;
arr = [1, 2, 3];
arr = ["1", "2", "3"];

如果我们在ts文件中写入错误的语法,如

var arr: Array | Array;
arr = [1, "2", 3];

可以看到webstrom会出现错误提示
在这里插入图片描述
此时去编译它,终端也会报错
TypeScript学习总结_第1张图片
但是js文件还是会被编译出来,为:

var arr;
arr = [1, "2", 3];
  1. 接口
    一系列抽象方法的声明,特征值的集合,由具体的去实现。
interface Father {
   money: number
}
interface Mother {
   appearance: string
}
interface Person extends Father, Mother{ // 多继承
   firstName: string,
   lastName: string,
   age: string | number,
   showName: () => string
}
var p1:Person = { //实例化一个对象
   money: 10000000,
   appearance: "handsome",
   firstName: "frank",
   lastName: "david",
   age: 18,
   showName: ():string => "frank david" // 少一个属性/方法编译会报错
}
console.log(p1);

该ts文件被转译后为

var p1 = {
    money: 10000000,
    appearance: "handsome",
    firstName: "frank",
    lastName: "david",
    age: 18,
    showName: function () { return "frank david"; } // 少一个属性/方法编译会报错
};
console.log(p1);

如果我们在p1对象中不写某些接口中定义的属性,则编译时会报错,额外增加属性亦然。

var p1 = {
    money: 10000000,
    //  appearance: "handsome", // 不写这个属性
    myprop: "123", // 增加一个接口中未定义的值
    firstName: "frank",
    lastName: "david",
    age: 18,
    showName: function () { return "frank david"; } // 少一个属性/方法编译会报错
};

再写一个数组的例子

interface List {
    [index:number]: string
}
var list:List = ["1", "2", "3"];
list[4] = "4";
console.log(list);

转译为js文件后

var list = ["1", "2", "3"];
list[4] = "4";
console.log(list);
  1. 类与对象
    一个demo
interface Bank { // 接口
   deposit:number
}
class GrandFather {
   money: number
   constructor() {
       this.money = 1000000000;
   }
}
class Father extends GrandFather{
   lastName: string
   constructor() {
       super();
       this.lastName = "david ";
   }
   doHappy() {
       console.log("drink");
   }
}
class Son extends Father implements Bank{ // 子类只能继承一个父类,但支持多重继承
   deposit: number //实现接口中的抽象属性
   name: string
   public sex:string // 默认就是public
   protected achievement: string // 被保护的成员
   private secret: string; // 私有成员
   static happyThing: string // 静态成员
   constructor(name) {
       super();
       this.name = name;
       this.sex = "man";
       this.secret = "something";
       this.deposit = this.money;
       this.achievement = "100"
   }
   showFullName():string {
       return this.lastName + this.name
   }
   showMoney():number {
       return this.money;
   }
   doHappy():void { //将方法重写
       console.log("study");
   }
}
Son.happyThing = "study";

var s = new Son("FRANK");
console.log(s.showFullName());
console.log(s.showMoney());
s.doHappy()
console.log(s instanceof Son, s instanceof Father, s instanceof GrandFather );
console.log(s);
// console.log(s.secret); // 私有成员变量不能直接访问
// console.log(s.achievement); // 被保护的成员,只能由自身获取父类及子类访问

可成功编译为js文件,在node环境运行,结果为

david FRANK
1000000000
study
true true true
Son {
 money: 1000000000,
 lastName: 'david ',
 name: 'FRANK',
 sex: 'man',
 secret: 'something',
 deposit: 1000000000,
 achievement: '100'
}

在学习中还看到了“鸭子类型”的概念

interface IPoint {
   x:number
   y:number
}
function addPoints(p1:IPoint,p2:IPoint):IPoint {
   var x = p1.x + p2.x
   var y = p1.y + p2.y
   return {x:x,y:y}
}

// 正确
var newPoint = addPoints({x:3,y:4},{x:5,y:1})

// 错误
// var newPoint2 = addPoints({x:1},{x:4,y:3})

我现在对其的理解是,可以用来校验实参和函数返回值是否符合接口。

  1. 命名空间
    避免重名问题,定义命名空间区分
    定义一个IShape.ts
namespace namespace1 {
   export interface IShape { // 对外暴露一个接口
       draw():string
   }
   export namespace Father { // 嵌套的命名空间
       export class Son {
           waste() {
               console.log("waste");
           }
       }
   }
}

定义一个Circle.ts,引入模块

/// 
namespace Drawing {
    export class Circle implements namespace1.IShape{
        public draw(): string {
            const str = "draw a circle";
            console.log(str);
            return str;
        }
    }
}

最后定义一个TestDraw.ts

/// 
/// 
const context = new Drawing.Circle();
context.draw();

const context1 = new namespace1.Father.Son();
context1.waste();

在终端输入指令

tsc --out app.js TestDraw.ts

文件转译后,在node环境下运行,输出

draw a circle
waste

模块

定义一个IShape.ts文件,对外暴露一个接口

export interface IShape { // export关键字,导出模块
    draw();
}

定义一个Circle.ts文件,引入IShape.ts模块,对外暴露一个类

import shape = require("./IShape"); // import关键字,引入模块
export class Circle implements shape.IShape {
    public draw() {
        console.log("draw a circle");
    }
}

定义一个Test.ts文件,引入Circle模块,创建实例

import circle = require("./Circle");
const c = new circle.Circle();
c.draw(); // 原型方法

接下来将其转换为js文件,由于我要将js在node环境下运行,遵循CommonJS规范,故输入指令

tsc --module commonjs Test.ts

(若遵循AMD规范,则为)

tsc --module amd Test.ts

之后文件都被转译了,在node环境运行Test.js文件,输出

draw a circle

声明文件

这个过程直接在菜鸟教程上看下吧,讲的很详细
参考
等我以后真正使用,并了解完善时再补充

你可能感兴趣的:(前端技术拓展)