搜尋
首頁web前端前端問答一篇文章帶你TypeScript入門(整理總結)

這篇文章為大家帶來了關於TypeScript入門的相關知識,希望對大家有幫助。

一篇文章帶你TypeScript入門(整理總結)

前言

ts是什麼? ts其實是TypeScript的一個簡稱,就跟JavaScript簡稱為js一樣,官方給的解釋是,ts它是js的超集,其實js的程式碼本質上都是ts編譯的,例如寫一個js程式碼document.write () ,上面的提示就是ts,如圖:

一篇文章帶你TypeScript入門(整理總結)
系統裡面寫的是ts程式碼,所以ts是js的超集,是給js加入拓展功能的語言,這樣的語言曾經還有一個叫as,但是這個語言已經沒了,它其實就是flash語言。但我麼開發需要完善js的話,必須得有這樣的東西,所以微軟拿著這個as的語法開發了ts這個語言,也就是說as和ts的語法基本上是一樣的,只不過ts是微軟開發的,然後推廣的不錯,現在隨著我們程式設計越來越全民化,ts使用的也就越來越多,包括在找工作中,如果你的薪資是在12k以上的話,基本上都會問你會不會ts,現在的程式設計很多情況下都是用到ts,因為它能為js加入拓展功能,

例如:可以進行各種各樣的模組化開發,像之前提到的AMD ,CMD開發,CommonJS,es6的模組化規格。假設現在在客戶端開發,有沒有一種開發場景,可以用AMD,也可以用CMD,CommonJS,es6的,

#答案是沒有,因為CommonJS是只能在nodejs中使用,es6的模組化開發只能在伺服器中使用,它們都是有各自限制的。

但是ts中,想用什麼都可以,它是支援全場景的。 ts它比較像後端,他的文法跟java最相似,這樣有什麼好處?大家知道js是弱型別語言,例如一個變數先定義一個數字型,然後再重新賦值一個字串型的,這樣的話這個變數的型別就改變了,這種弱型別開發是對專案有一定的安全隱患的,

例如就用這個變數去做其他事情,它有可能變成其他類型的數據,所以對開發來說是有安全隱患的,所以必須得有ts來規範js開發,消除這個安全隱患,這就是為什麼ts像java、#c這些後端語言,這些強類型語言定義變數的時候,需要先宣告這些變數的類型是什麼,一旦定義這個變數的類型後,後期是不允許修改類型的,有了這樣的規範約束後,開發就更安全了。

現在ts使用的場景是非常廣泛:js的提示(編輯器內建了規範語法的ts),主流框架vue,react在底層寫框架的時候用的也是ts。

說這麼多,下面直接介紹ts,也就是TypeScript。


TypeScript

簡介

#ts是給js新增特性的擴充語言。

  1. TypeScript是由微軟開發的一款開源的程式語言。
  2. TypeScript是JavaScript的超集,遵循最新的es6、es5規格。 TypeScript擴充了JavaScript的語法。
  3. TypeScript比較像後端java、C#這樣的物件導向語言,可以讓js開發大型企業專案。
  4. Google也大力支持TypeScript的推廣,Google的angular2.x 就是基於TypeScript語法。
  5. 最新的vue、React也可以整合TypeScript。
  6. nodeJs礦建Nestjs、midway中用的就是TypeScript語法。

可以增加js的功能有

  • 類型批次與編譯時類型檢查
  • 類型推論
  • 類型擦除
  • #介面
  • 枚舉
  • Mixin
  • 泛型程式設計
  • 名字空間
  • 元組
  • Await
  • 類別
  • 模組
  • lambda 函數的箭頭語法
  • 可選參數以及預設參數

js是一個弱型別的語言,但ts是強型別的,語法很相像,但ts算是擴展的js的語法,ts透過型別註解,提供編譯js時的靜態型別檢查。


編譯

ts無法直接執行,所以只能編譯成js運行。類似sass用來編譯css,不能直接執行。
編譯工具- typescript

在全域任意位置下,先偵測是否已安裝過ts

tsc --version

一篇文章帶你TypeScript入門(整理總結)

npm install -g typescript

一篇文章帶你TypeScript入門(整理總結)

偵測是否安裝成功:

tsc -v

ts檔案的後綴是ts,編譯指令:

tsc 被编译的文件

會在被編譯檔案的同級目錄下產生一個同名的js檔案。

產生自訂名稱路徑的檔案:

tsc 被编译的文件 --outFile 编译后的文件路径

初始化命令:

tsc --init

執行初始化命令後,會產生一個tsconfig.json文件,如下:

一篇文章帶你TypeScript入門(整理總結)

其中常用配置项说明:

代表ts要转换后js版本

"target": "es5"

如果ts是以模块形式书写的,使用什么样的模块化规范,默认是commonJS

"module": "amd"

配置输出目录,可自己设置

"outDir": "./"

一篇文章帶你TypeScript入門(整理總結)

上面的配置项配置好以后,执行监视命令会自动编译:

tsc -w

使用amd规范的时候,需要将require.js文件拷贝到项目根目录下,且需要一个出口文件:

<script></script>

将ts编译成js,自动生成目标js文件

tsc 目标js文件

一篇文章帶你TypeScript入門(整理總結)

一篇文章帶你TypeScript入門(整理總結)


ts基础类型

在定义变量的时候需要指定类型,且定义好类型以后就不能改变他的类型了 - 强类型。

数值型

let decLiteral: number = 6; // 十进制
let hexLiteral: number = 0xf00d; // 16进制
let binaryLiteral: number = 0b1010; // 二进制
let octalLiteral: number = 0o744; // 8进制

let num: Number = 5; // 此时大写Number类型可以赋值为数值对象类型
num = new Number(10);

布尔值

let isDone: boolean = false;let bool: Boolean = true; // 首字母大写的类型可以赋值为对象类型

boolean这种类型只能赋值两个值:true/false

var bool: boolean = true
 var bool: boolean = new Boolean(true)

Boolean这种类型除了上面的字面量方式的两个值,还可以使用构造函数方式

var bool: Boolean = false;var bool: Boolean = new Boolean(true)

字符串

var str: string = 'asdfasdf';var str1: String = new String('43563456')

数组

ts写的数组,其中的数据必须是同一个类型,但不指定长度
数组中所有数据的值类型必须是数字

var arr: number[] = [1,2,3];var arr: Array<string> = ['a','b'];</string>

声明二维数组

var arr: number[]var brr: number[][] = [
    [1,2,3],
    [4,5,6]];

元组 Tuple

ts中的元组表示不同类型数据组成的集合,通常会固定长度,同样可以使用下标访问元素和给元素赋值

元组中就可以放不同类型的数据
元组在定义的时候就将长度固定了

var x: [string,number] = ['a',2];console.log(x);console.log(x[0]);

错误

x[2] = 20

不能加长度

let x: [string, number];x = ['hello', 10];x[2] = 'world'; // 不能加长度

可以给元素push一个值,这个值必须是string或number的类型,其他类型不允许

x.push('aaaa')

错误

 x.push(true) // 错误

当给元组中并不存在的下标进行赋值的时候,会使用联合类型:

x[3] = 'world'; // OK, 字符串可以赋值给(string | number)类型x
6] = true;// Error, 布尔不是(string | number)类型

枚举

ts中的枚举相当于在定义变量类型,这个类型有固定的取值范围,默认值从0开始,向后递增,使用指定的键来换换取到值,如果一个变量使用了这个类型,那他的值就必须从这个类型中选择,不能随便赋值:

枚举 - 必须使用指定的集合中的值
枚举类型,其实是给数字起了一些名字,让我们可以通过这个名字获取到对应的数字
默认情况,第一个名字对应的值是0,依次向后递增

enum Color {Red,Green,Blue};var c: Color = Color.Blue; // 2

如果给其中某一个名字赋值了,他后面的名字对应的值,是根据这里的值向后递增

enum Color {Red,Green = 5,Blue};var c: Color = Color.Blue; // 6

每个值可以指定

 enum Color {Red=3,Green = 4,Blue=2};
 var c: Color = Color.Blue; // 2

可以指定非数字的值

enum Color {Red='男',Green = '女',Blue='不男不女'};var c: Color = Color.Blue; // 不男不女

通过对应值的数字获取到对应的名字 - 名字是字符串类型

enum Color {Red,Green=5,Blue};var c: string = Color[6] // Blue

如果我们指定了其中的值是非数字型的,就不能使用这个骚操作了

enum Color {Red='red',Green = 'green',Blue='blue'};var c: string = Color['red']; // 这个地方的值必须是数字才行

Any

Any类型,表示弱类型,也就是当我们定义一个变量的时候,不能确定变量值的类型的时候,这个类型我们又爱又恨
使用:

var a:any = 20var b:any = 'asdfasdf'var c:any = [1,2,3]

注意:本来我们使用ts编写代码,为的是限制类型,减少安全隐患,但是如果使用了any类型,就跟直接写js一样了,失去了意义,所以若非迫不得已,尽量不要使用。

Void

这种类型,一般用于函数执行后,不使用return返回结果的时候,就指定返回结果是void
声明变量的时候不使用它 - 当函数没有返回值的时候,返回类型指定为void

function fn(a:number,b:number):void{
   console.log(a*b);}

Undefined

这种类型主要用于参数和返回值,用于变量毫无意义,因为定义一个变量指定为undefined类型时,以后也就只能是undefined类型了,函数中的用法:

function fn(num:number|undefined):number|undefined{
    return num;}

undefined - 未定义类型

var a:undefined = undefined

定义变量不用undefined,因为定义了没有用

通常会用在函数的参数里面
希望fn函数的参数a是可选项

function fn(a:number|undefined):void{
    console.log(a);}fn(undefined)

函数可选项
参数名后面,类型的冒号之前加 ? 表示这个参数是可选项
undefined通常用在函数返回值,如果返回的是undefined就需要在返回值的地方指定undefined类型

function fn(a?:number):number|undefined{
    return a;}fn()

Null

null类型 - 空 - 这个数据要被销毁啦
通常在定义复杂数据类型,且在后期需要给赋值为null的时候使用

var a:number|null = 10;

使用变量a计算 - 完成

让内存回收这个变量

a = null

Never

never类型表示永远不存在的值的类型,例如,一个函数中抛出的错误,函数中有死循环永远不可能返回 …

function fn():never{
    throw new Error('错误')}function fn():never{
    return fn()}fn()

Object

对象类型:

var obj: object = {
    name:"张三"}

错误写法 - 对象默认不允许添加键值对

obj.name = '张三';

类型断言

如果在一段代码执行后的类型种类的可能性比较多,就需要假设这是一种什么类型 - 这种操作就叫做断言。

如果一个表达式的结果有可能是多种类型,最终需要肯定其中一种

var abcd: any = [1, 2, 3, 4, 5];

断言abcd变量是一个数组

(abcd as [string,number]).push(6)(abcd as string) += 'ddd'

函数声明

在ts中,函数定义比起js中,多了参数类型和返回值的类型定义:
函数的定义,参数的类型声明,返回值的类型声明

function fn(a:number,b:number):number{
    // console.log(a+b);
    return a+b}var res = fn(1,2)

参数默认值

function fn(a:number,b:number=3):number{
    return a+b}var res = fn(1)

但是在表示参数为可选项的时候,写法稍有不同:
参数可选项 - ?表示可有可无

function fn(a:number,b?:number):number{
    if(!b){
        return a+5
    }
    return a+b}// var res = fn(1)var res = fn(1,3)

带有默认值的参数,必须放在所有参数的最后面
可选项参数,必须放在所有参数的最后面

展开运算符和合并运算符同样可以使用在ts中,但是要注意运算符后面的变量的类型设置。

计算不定实参的和

function  sum(...arr:Array<number>){
    var sum = 0;
    for(var i=0;i<arr.length><p>函数重载:通过 为同一个函数提供多个函数类型定义 来实现多种功能的目的。例:</p>
<pre class="brush:php;toolbar:false">function outputName(name:string):string{
    return "我叫"+name}var s1 = outputName('张三')console.log(s1);function outputAge(age:number):string{
    return "我今年"+age+"岁了"}var s2 = outputAge(12)console.log(s2);

有多个函数结构非常类似,可以声明一个函数的结构,让函数遵循这个结构

function output(name:string):string;  定义了一个函数结构 - 名字叫output
function output(age:number):string;

function output(name:any):any
{
    return "我今年"+name+"岁了";
}

var res = output(12)
console.log(res);

var res1 = output('李四')
console.log(res1);

var res2 = output(true)  报错的,因为函数的结构要求是参数string或number
console.log(res2);

ts中的类

定义

定义方式跟es6的定义方式类似

class 类名{
    constructor(){

    }}
class Person{
    // 静态属性 - 用类名直接调用的属性
    static weight:number;

    // 类的属性要定义在这里
    name:string; // 表示类中有一个属性叫name
    // 在ts类中,属性和方法前面可以加一个修饰符:
    /*
        public - 公开的 - 在哪里都能用
        protected - 受保护的
        private - 私有的
    */
    public age:number; // public可以省略的
    protected sex:string; // 受保护的只能在类里面用,类的外面不能用的
    private height:number; // 私有的只能在类里面使用,类外面不能用
    constructor(name:string,age:number,sex:string,height:number,weight:number){
        // 给属性赋值的时候,必须在这个类中是本来就有这个属性才行
        this.name = name

        this.age = age

        this.sex = sex

        this.height = height;

        // this.weight = weight;
        Person.weight = weight;

        this.init()
    }

    private init(){
        // console.log(this.age);
        // console.log(this.sex);
        console.log(this.height);
        console.log("这是初始化方法");
    }

    static fly(){
        console.log("飞的更高");
    }
}

var p = new Person('张三',12,'男',120,150)
console.log(p);
// console.log(p.age);
// console.log(p.sex); // 受保护的属性不能类的外面使用
// console.log(p.height) // 私有属性不能类的外面使用 

// p.init()

console.log(Person.weight);
Person.fly()

继承

ts中类的继承和es6的继承是一样,使用extends关键字,然后在构造函数中调用super函数相当于在调用父类的构造函数。

如果子类和父类有同名的方法,在子类调用这个方法的时候先在子类里面找,如果子类没有再到父类里面找。

class Person{
    // 静态属性 - 用类名直接调用的属性
    static weight:number;

    // 类的属性要定义在这里
    name:string; // 表示类中有一个属性叫name
    // 在ts类中,属性和方法前面可以加一个修饰符:
    /*
        public - 公开的 - 在哪里都能用
        protected - 受保护的
        private - 私有的
    */
    public age:number; // public可以省略的
    protected sex:string; // 受保护的只能在类里面用,类的外面不能用的
    private height:number; // 私有的只能在类里面使用,类外面不能用
    constructor(name:string,age:number,sex:string,height:number,weight:number){
        // 给属性赋值的时候,必须在这个类中是本来就有这个属性才行
        this.name = name

        this.age = age

        this.sex = sex

        this.height = height;

        // this.weight = weight;
        Person.weight = weight;

        this.init()
    }

    private init(){
        // console.log(this.age);
        // console.log(this.sex);
        console.log(this.height);
        console.log("这是初始化方法");
    }

    static fly(){
        console.log("飞的更高");
    }
}

var p = new Person('张三',12,'男',120,150)
console.log(p);
// console.log(p.age);
// console.log(p.sex); // 受保护的属性不能类的外面使用
// console.log(p.height) // 私有属性不能类的外面使用 

// p.init()

console.log(Person.weight);
Person.fly()

类的修饰符

在类中定义属性的时候,提供了3个修饰符:

  1. public:公有的 - 在类里面、子类中、类的外面都可以访问
  2. protected:受保护的 - 在类里面、子类中可以访问,在类外面不能访问
  3. private:私有的 - 在类里面可以访问,在子类和类的外面都不能访问

静态属性和方法

es5中静态方法使用:

// 模拟jquery的封装function $(element){
	return new Ele(element);}$.get = function(obj){
    }function Ele(element){
    this.element = document.getElementById("#"+element);}Ele.prototype.css = function(attr,value){
    if(value){
    	this.element.style[attr] = value;
    }else{
        return window.getComputedStyle(this.element)[attr];
    }}$("#box").css("color","red");

在ts中定义静态的属性和方法使用static关键字。在静态方法中无法访问到普通的属性,只能访问到静态的属性。

class Person{
    public name:string = "张三";
	static age:number = 20;
    constuctor(){

    }
    static print1(){
        console.log(this.name); // 访问不到
    }
	static print2(){
        console.log(Person.name); // 可以访问到
    }}Person.print1();Person.print2();

属性可以设置为只读

多态

面向对象的三大特点:封装、继承、多态

含义:多态就是说,父类定义一个方法不去实现,让继承它的子类去实现,这样每个子类都会有不同表现。多态其实也是继承的一种表现。

// 父类 - 动物类class Animal{
    public tui:string = "有腿";
    public eat(){
        console.log("喜欢吃");
    }
    public sport(){
        console.log("能走");
    }
    public tuiNum(){
        console.log("有多条腿");
    }}// 子类 - 人类class Person extends Animal{
    sport(){
        console.log("直立走");
    }
    tuiNum(){
        console.log("两条腿");
    }}var p = new Person();console.log(p.tui); // 有腿p.eat(); // 喜欢吃p.sport(); // 直立走p.tuiNum() // 两条腿// 子类 - 鸟类class Bird extends Animal{
    sport(){
        console.log("很少走,通常都在飞");
    }
    tuiNum(){
        console.log("两条腿");
    }}var b = new Bird();console.log(b.tui);b.eat();b.sport(); // 很少走,通常都在飞b.tuiNum(); // 两条腿// 子类 - 狗类class Dog extends Animal{
    sport(){
        console.log("通常都在跑,很少走");
    }
    tuiNum(){
        console.log("4条腿");
    }}var d = new Dog();console.log(d.tui);d.eat();d.sport(); // 通常都在跑,很少走d.tuiNum(); // 4条腿

效果:

多态的表现
一篇文章帶你TypeScript入門(整理總結)

**小总结:**多态就是多个子类继承自同一个父类,但是每个子类将继承下来的属性或方法做了改善,最终每个子类表现出来的结果是不一样的。

多态其实源于继承,也是方法的重载。

抽象类

在实际工作中,项目负责人通常会写一些标准(类似于大纲),然后将标准交给具体实现的攻城狮,由攻城狮将这个标准进行具体化开发。

ts中的抽象类就是为制作标准的。抽象类不能被实例化,只能被派生类继承并实现。

定义抽象类使用abstract关键字来修饰类。

abstract class Animate{
    public name:string;
	constructor(name:string){
		this.name = name;
    }}var ani = new Animate("动物"); // 报错class Dog extends Animate{
    constructor(name:string){
		super(name);
    }}var d = new Dog("小黄");

这种结构没有意义。跟普通的继承是一样的,并不能体现出标准的特殊。在抽象类中通常会有抽象方法 - 使用abstract修饰的方法。

抽象方法必须在抽象类中,且只需要定义方法结构,不要具体的实现。但是派生类中必须实现(完善)抽象方法。

abstract class Animate{
    public name:string;
	constructor(name:string){
		this.name = name;
    }
    abstract eat():void; // 抽象方法}class Dog extends Animate{
    constructor(name:string){
		super(name);
    }
    eat(){ // 实现了抽象方法
        consolelog("小狗吃粮食");
    }}

这个结构就能体现出标准的特殊:规定子类必须包含eat方法。

抽象方法只能放在抽象类中。

抽象类存在的意义就是被其他类继承,是其他类的基类。

接口

抽象类只能给方法定义标准,对于属性限制不够,所以ts设计了接口语法,它定义了属性和方法的规范,起到限制和规范的作用。接口并不关心这些类的内部状态数据,也不关心这些类里方法的实现细节,它只规定这批类里必须提供某些方法,提供这些方法的类就可以满足实际需要。

ts的接口跟别的主流服务器端语言的接口一样,同时还增加了更加灵活的接口类型,包括属性、函数、可索引和类等。

简单来说,接口也是在定义标准,只不过更加灵活和全面。

属性接口

属性接口专门为了约束属性而设计。

语法:

interface 接口名称{
    变量:类型;
    变量:类型;}

使用方式:

function printInfo(info:接口名称){
    console.log(info.属性名); // 属性名必须是接口定义过的,否则报错}

例:

// 以前对于数据的限制// 1.定义方法function printInfo():void{
    console.log(123);}printInfo();// 2.传入参数function printInfo(info:number):void{
    console.log(info);}printInfo(123);// 3.传入的参数对json限制function printInfo(info:{name:string}):void{
    console.log(info);}printInfo({
    name:"张三"});printInfo({ // 错误示例 - 键在函数中不存在
    sex:"男"});// 这种函数只能对一个键做限制,要做批量限制很麻烦,要写很多函数// 使用接口限制// 1.定义接口interface info {
    name:string;
    sex:string;}// 2.定义函数使用接口类型function printInfo(data:info){
    console.log(data.name);
    console.log(data.sex);
    // console.log(data.age); // 错误 - info中没有age键}// 3.使用printInfo({
    name:"张三",
    sex:"男",
    age:20 // 错误 - info中没有age键});var obj = {
    name:"张三",
    sex:"男",
    age:20}printInfo(obj); // 正确// 接口可以批量对变量进行约束 - 参数的顺序可以不一样,但是不能少参数

定义接口中的可选参数:

interface info{
    name:string;
    sex?:string;
    [propName:string]:any // 这里表示其他属性也可以加,也可以不加
}
// 这个接口表示name是必须,sex是可选项
// 在属性前面可以使用readonly来修饰属性不可以修改

例:

// 对jquery的ajax的封装$.ajax({
    type: "GET",
    url: "test.json",
    data: {username:$("#username").val(), content:$("#content").val()},
    dataType: "json"             });// 定义接口interface Config{
    type?:string;
    url:string;
    data?:string;
    dataType?:string;}// 使用接口类型封装ajaxfunction sendAjax(config:Config){
    var xhr = new XMLHttpRequest();
    }// 调用sendAjax({
    url:"",
    });

函数接口

函数接口是专门为了约束函数的参数和返回而设计。

语法:

interface 接口名称{
    (参数:类型):返回值类型}

例:

// 加密的接口interface encrypt{
    (key:string,value:string):string;}var md5:encrypt=function(key:string,value:string):string{
    //模拟操作
    return key+value;}console.log(md5('name','zhangsan'));

可索引接口

可索引接口是对数组、对象等有索引的数据做约束。

对数组的约束接口:

interface userArr {
    [index:number]:string; // 表示索引必须为数字,数据必须是字符串}

使用:

var arr:userArr = ["张三","李四"]

对对象的约束:

interface userObj{
    [index:string]:string;}

使用:

var obj:userObj = {name:"张三"}

泛型

泛型:软件工程中,我们不仅要创建一致的定义良好的API,同时也要考虑可重用性。 泛型不仅能够支持当前的数据类型,同时也能支持未来的数据类型,这在创建大型系统时为你提供了十分灵活的功能。

通俗理解:泛型就是解决 类 接口 方法的复用性、以及对不特定数据类型的支持(类型校验)

泛型方法:

function getInfo<t>(value:T):T{
    return value;}getInfo<number>(123);getInfo<string>('aaa');</string></number></t>

例:

// 约束函数传入number返回number,传入string返回string// 以前:function fn(a:number):number;function fn(a:string):string;function fn(a:any):any{
    return a;}// 使用泛型function fn<t>(a:T):T{
    return a;}fn<number>(234);fn<string>("abc");</string></number></t>

命名空间

多人合作开发项目的时候,避免不了会有函数、变量、类等数据的命名冲突。但是ts不允许出现同名的类、函数、变量(const定义的),这时候就需要使用命名空间来解决这个问题。

命名空间其实就单独做一个作用域,在当前命名空间下的数据跟别的命名空间下的数据重名也不会产生冲突。

命名空间语法:

namespace A{ // namespace 命名空间名称{} 
    class Animal{
        constructor(){
            console.log("A命名空间下的动物类");
        }
    }}// 使用动物类的时候A.Animal()

例:
命名空间

工作中一个项目都是协作开发,每个人负责一个文件,避免不了函数、变量、类、接口会重名。
但是在ts文件,不允许类、函数、let、const 重名
命名空间就是解决这个问题的。
命名空间:就是开辟自己的作用域

// 定义命名空间:namespace 空间名字{}
namespace A{
    // 相当于定义了一个单独的作用域叫A
    export class Animal{
        name:string;
        constructor(name:string){
            this.name = name;
        }
    }
}

namespace B{
    export class Animal{
        age:number;
        constructor(age:number){
            this.age = age;
        }
    }
}

// 在这里实例化Animal类
// 使用命名空间:命名空间.数据
var a = new A.Animal("张三");
console.log(a.name); // 张三

var b = new B.Animal(20);
console.log(b.age); // 20

从结果中可以看到,同名的类处在不同的命名空间下是不会冲突的。

此时,A命名空间就是一个单独的模块,进行模块化开发的时候,需要将命名空间导出,也就是说一个命名空间就是一个模块,而不是一个单独的文件了。

例:

// 导出export namespace A{ // 将命名空间导出
    // 相当于定义了一个单独的作用域叫A
    export class Animal{
        name:string;
        constructor(name:string){
            this.name = name;
        }
    }}

导入的时候,导入当前文件,接收命名空间,通过命名空间来调用数据:

// 导入import { A } from "./demo"; // 导入的是一个命名空间var a = new A.Animal("张三"); // 实例化那个Animal

ts事件封装

为什么要封装?

因为在es5和es6中允许dom元素继承EventTarget,但是在ts中不允许继承。

所以需要重构EventTarget。

使用dispathEvent来抛发事件,需要使用Event。所以重构Event。

本质:观察者模式。

ts开发的规则

开发的时候通常都是在使用模块化开发

怎么进行模块化开发?一个模块一个类,通常类的首字母会大写,文件名称和类的名称保持一致。

封装

准备工作:

将ts配置文件中的module选项改成amd。

 "module": "amd",

更改输入输出目录:

"outDir": "./js", "rootDir": "./ts",

新建html,导入amd所使用的require.js。

配置导入文件以及异步推迟加载。

<script></script>

新建MyEvent.ts文件:

import MyTarget from "./MyTarget";export default class MyEvent{
    public type:string;
    [key:string]:any;
    public myTarget:MyTarget|null = null;
    public target:MyTarget|null = null;
    public data:any;
    constructor(type:string,data:any = null){
        this.type = type;
    }}

新建MyTarget.ts

import IListener from "./IListener";import MyEvent from "./MyEvent";export default class MyTarget{
    public listenerList:IListener = {};
    constructor(){

    }
    addEventListener(type:string,listener:Function):void{
        if(!this.listenerList[type]) this.listenerList[type] = [];
        this.listenerList[type].push(listener);
    }
    removeEventListener(type:string,listener:Function):void{
        if(!this.listenerList[type]) return;
        var index:number = this.listenerList[type].indexOf(listener);
        if(index>-1){
            this.listenerList[type].splice(index,1);
        }
    }
    dispathEvent(evt:MyEvent):boolean{
        var list:Function[] = this.listenerList[evt.type];
        if(!list) return false;
        evt.myTarget = this;
        evt.target = this;
        for(var i:number=0;i<list.length><p>新建IListener.ts文件</p>
<pre class="brush:php;toolbar:false">export default interface IListener{
    [key:string]:Array<function>;}</function>

在Main.ts中使用:

import MyEvent from "./MyEvent";import MyTarget from "./MyTarget";var doc = new MyTarget();var ev = new MyEvent("zi");ev.a = 10;// var ev1 = new MyEvent("ziji");// ev1.b = 20;// console.log(doc);doc.addEventListener("zi",handler1);doc.addEventListener("zi",handler2);doc.addEventListener("ziji",handler2);doc.dispathEvent(ev);doc.dispathEvent(ev);// doc.dispathEvent(ev1);function handler1(e:MyEvent){
    console.log(e + "----------------");}function handler2(e:MyEvent){
    console.log(e + "||||||||||||||||||||");
    (e.target as MyTarget).removeEventListener("zi",handler2);}

效果:

第二次抛发的事件被删除
一篇文章帶你TypeScript入門(整理總結)

更多编程相关知识,请访问:编程入门!!

以上是一篇文章帶你TypeScript入門(整理總結)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:CSDN。如有侵權,請聯絡admin@php.cn刪除
5个常见的JavaScript内存错误5个常见的JavaScript内存错误Aug 25, 2022 am 10:27 AM

JavaScript 不提供任何内存管理操作。相反,内存由 JavaScript VM 通过内存回收过程管理,该过程称为垃圾收集。

Vue3+TypeScript+Vite怎么使用require动态引入图片等静态资源Vue3+TypeScript+Vite怎么使用require动态引入图片等静态资源May 16, 2023 pm 08:40 PM

问题:Vue3+TypeScript+Vite的项目中如何使用require动态引入类似于图片等静态资源!描述:今天在开发项目时(项目框架为Vue3+TypeScript+Vite)需要动态引入静态资源,也就是img标签的src属性值为动态获取,按照以往的做法直接是require引入即可,如下代码:写上后代码波浪线报错,报错提示:找不到名称“require”。是否需要为节点安装类型定义?请尝试使用npmi--save-dev@types/node。ts(2580)在进行了npmi--save-d

如何使用Redis和TypeScript开发高性能计算功能如何使用Redis和TypeScript开发高性能计算功能Sep 20, 2023 am 11:21 AM

如何使用Redis和TypeScript开发高性能计算功能概述:Redis是一个开源的内存数据结构存储系统,具有高性能和可扩展性的特点。TypeScript是JavaScript的超集,提供了类型系统和更好的开发工具支持。结合Redis和TypeScript,我们可以开发出高效的计算功能来处理大数据集,并充分利用Redis的内存存储和计算能力。本文将介绍如何

Vue3中怎么使用TypeScriptVue3中怎么使用TypeScriptMay 13, 2023 pm 11:46 PM

如何声明字段名为枚举的类型?根据设计,type字段应该是一个枚举值,不应该由调用方随意设置。下面是Type的枚举声明,共有6个字段。enumType{primary="primary",success="success",warning="warning",warn="warn",//warningaliasdanger="danger",info="info",}TypeSc

使用Redis和TypeScript开发可扩展的前端应用程序使用Redis和TypeScript开发可扩展的前端应用程序Aug 01, 2023 pm 09:21 PM

标题:使用Redis和TypeScript开发可扩展的前端应用程序引言:在当今互联网时代,可扩展性是任何应用程序的关键要素之一。前端应用程序也不例外。为了满足用户日益增长的需求,我们需要使用高效可靠的技术来构建可扩展的前端应用程序。在本文中,我们将介绍如何使用Redis和TypeScript来开发可扩展的前端应用程序,并通过代码示例演示其应用。Redis简介

在PHP中使用TypeScript编写更好的代码在PHP中使用TypeScript编写更好的代码Jun 19, 2023 pm 06:31 PM

随着JavaScript的不断发展,前端工程师们已经逐渐意识到JavaScript本身存在的一些问题,例如缺乏类型检查和模块化,这些问题在大型项目中经常会造成混乱和错误。为了解决这些问题,TypeScript应运而生,成为前端开发中越来越受欢迎的语言。而在后端开发领域中,PHP一直是一种极其流行的脚本语言。因此,结合TypeScript来开发PHP的应用程序

Vue3相较于Vue2的变化:更好的 TypeScript 类型推导Vue3相较于Vue2的变化:更好的 TypeScript 类型推导Jul 07, 2023 pm 01:05 PM

Vue3相较于Vue2的变化:更好的TypeScript类型推导Vue是一种流行的JavaScript框架,用于构建用户界面。而Vue3是Vue框架的最新版本,在Vue2的基础上进行了大量改进和优化。其中之一是在TypeScript类型推导方面的提升。本文将介绍Vue3在类型推导方面的改进,并且通过代码示例进行说明。在Vue2中,我们需要手动为Vue组件

Vue3中TypeScript怎么使用Vue3中TypeScript怎么使用May 18, 2023 pm 08:52 PM

如何声明字段名为枚举的类型?根据设计,type字段应该是一个枚举值,不应该由调用方随意设置。下面是Type的枚举声明,共有6个字段。enumType{primary="primary",success="success",warning="warning",warn="warn",//warningaliasdanger="danger",info="info",}TypeSc

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
2 週前By尊渡假赌尊渡假赌尊渡假赌
倉庫:如何復興隊友
4 週前By尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒險:如何獲得巨型種子
4 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

WebStorm Mac版

WebStorm Mac版

好用的JavaScript開發工具

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器

SublimeText3 英文版

SublimeText3 英文版

推薦:為Win版本,支援程式碼提示!