65.9K
CodeProject 正在变化。 阅读更多。
Home

TypeScript 快速参考

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.93/5 (11投票s)

2016 年 8 月 31 日

CPOL

9分钟阅读

viewsIcon

31030

在本文中,我们将学习 TypeScript。

目录                                                                                                                       

  1. 什么是 TypeScript
  2. 数据类型
  3. 枚举
  4. 函数
  5. 函数重载
  6. 类与对象
  7. 构造函数
  8. 继承
  9. 访问修饰符
  10. 静态函数与属性
  11. 接口

什么是 TypeScript

TypeScript 是 JavaScript 的超集,它具有可选的静态类型和基于类的面向对象编程语言。它具有面向对象编程的特性,如类、构造函数、对象、接口,并始终支持原始数据类型。OOP 概念可以在这种语言中实现。TypeScript 的代码比 JavaScript 更具可读性,它是开源且免费的。它由 Microsoft 创建,并于 2012 年 10 月发布。

现在我们将创建一个简单的应用程序。

让我们开始吧:  

使用 Visual Studio 2015 > 文件 > 新建 > 项目 创建一个新项目

ChooseTemplate

单击“确定”按钮后,将创建一个需要 TypeScript 引用的项目。

projectst

我们可以看到上面图片中的 app.css 文件,它是 CSS 文件,您可以将 CSS 样式代码放在此文件中;我们看到 app.ts,它是一个 TypeScript 文件,ts 扩展名表示 TypeScript 文件,您可以始终将 TypeScript 代码放在 ts 文件中。

创建 ts 文件

右键单击您的项目 >> 单击“添加” >> 单击“JavaScript 文件”并命名为“Welcome.ts”,然后单击“确定”按钮。下面是代码。

// Class name welcome
class welcome { 
    element: HTMLElement;
     // constructor
    constructor(element: HTMLElement) {
        this.element = element;
        this.element.innerHTML= "Welcome To TypeScript";
    }
}
 // window onload event, when page open then call this onload event 
window.onload = () => {
    // get html divcontent 
    var elh = document.getElementById('divcontent'); 
    // create new object and call constructor with elh paramitter
    var _welcomeobj = new welcome(elh);    
};

让我们来解释一下 Welcome.ts

我们创建了 Welcome 类。它有一个元素属性和一个构造函数,该构造函数接受一个参数,该参数的类型为 HTMLElement。当我们创建 Welcome 类的实例时,构造函数会自动调用。我们只给了 div id,即 index page。我们知道如何使用 JavaScript 获取 div id。为了捕获 div id,我们使用了 document.getElementById。“Welcome To TypeScript”已被分配在构造函数中。

创建 Index Page 现在我们将创建 Index.html 页面以在浏览器上显示我们的结果。下面是代码。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <title>My Fisrt TypeScript's Application</title>
    <link rel="stylesheet" href="app.css" type="text/css" />
    <script src="Welcome.js"></script>
</head>
<body>
    <h1>My Fisrt TypeScript's Application</h1>

    <div id="divcontent"></div>
</body>
</html>

我们刚刚在 index.html 页面中添加了 Welcome.js 的引用。因为我们在编码中使用了 Welcome.js。它是我们的 TypeScript 文件。

最终输出

hellowresult

数据类型

背景:我们知道每种编程语言基本上都有两种数据类型,一种是原始数据类型,另一种是自定义数据类型。但今天我们将讨论原始数据类型,如 Boolean、Number、String、Any、Array、Enum

syntax

Syntax

创建 ts 文件

右键单击您的项目 >> 单击“添加” >> 单击“JavaScript 文件”并命名为“DataType.ts”,然后单击“确定”按钮。下面是代码。

class DataType {

    // boolean Type
    Status: boolean = true; // output ture
    // number Type
    Amount: number = 100; // output 100
    // number always support like decimal,hex,binary,octal
    Price: number = 50.5; // output 50.5
    // string Type
    Subject: string = "TypeScript"; // TypeScript
    // any like dynamic type 
    Value: any = 5;

    // we know that when class object will be Created then automatic call constructor 
    constructor() {
        console.log(this.Status);
        console.log(this.Amount);
        console.log(this.Price);
        console.log(this.Subject);
        console.log(this.Value);
    }
}
window.onload = () => {
    // Create class object 
    var val = new DataType();
}

让我们来解释一下数据类型 Boolean:

// boolean Type
 Status: boolean = true; // output ture

我们可以看到上面一行,Status 变量接受了 bool 类型的数据。如果我们把字符串或数字类型的数据放入 Status 变量中,就会显示错误。

字符串

Subject: string = "TypeScript"; //output is TypeScript
Name:string='Mamun'; //output is Mamun

String 是文本数据。TypeScript 中使用双引号(")或单引号(')。String 数据类型没有双引号或单引号就会显示错误。

1. Number:Number 是 TypeScript 中非常有趣的数据类型。Number 可以接受,例如:1. 小数

decimal: number = 10;

2. 十六进制

hex: number = 0xf00d;

3. 二进制

binary: number = 0b1111;

4. 八进制

octal: number = 0o744;

输出

DataTypeOutput

枚举

Enum 是对 JavaScript 标准数据类型集合的有用的补充。数据存储在 enum 中。Enum 的数据在 enum 块外不会修改。默认情况下,Enum 从 0 开始对其成员进行编号。但可以手动更改。

让我们开始吧:  

创建 ts 文件:右键单击您的项目 >> 单击“添加” >> 单击“JavaScript 文件”并命名为“SalaryCal.ts”,然后单击“确定”按钮。下面是代码

enum SalaryHead {
    // these are %
    Basic = 50,
    Houserent = 30,
    Medical = 10,
    Conveyance = 10
}
class SalaryCal {
    // let gross salary is 50000,Gross Salary will be given from IU in real wrold 
    Gross: number = 50000;
    // Calculate Basic from gross slary
    BasicSalary: number = (this.Gross * SalaryHead.Basic) / 100;
    // Calculate House Rent from gross slary
    Houserent: number = (this.Gross * SalaryHead.Houserent) / 100;
    // Calculate Medical from gross slary
    Medical: number = (this.Gross * SalaryHead.Medical) / 100;
    // Calculate Conveyance from gross slary
    Conveyance: number = (this.Gross * SalaryHead.Conveyance) / 100;

    // we can not modify enum valu without enum block
   // SalaryHead.Basic=60;

    constructor() {
        // Now we will check sum of salary head and gross are equal.
        if ((this.BasicSalary + this.Houserent + this.Medical + this.Conveyance) == this.Gross) {
            console.log("Both are equal");
        }
        else {
            console.log("Both are not equal");
        }
    }   
}

window.onload = () => {
    // Create class object 
    var val = new SalaryCal();
}

让我们来解释一下 enum

上面我们可以看到我们声明了一个名为“SalaryHead”的 enum。已经分配了一些 enum 的属性。当它需要在使用我们的应用程序时,只需调用 enum。但是 enum 的属性在 enum 范围外永远不会改变。现在,如果调用 enum 的属性,我们将得到分配的值。

enum Status {
    IsDelete,
    IsPending,
    IsApprove
};

上面是 Status enum,它包含三个状态,如 IsDelete、IsPending 和 IsApprove。

调用: Status[0] 

输出: IsDelete

函数

什么是函数:一起执行的语句组,用于解决特定任务。每个函数都应该解决一个单一的任务。我们使用函数的原因有很多,例如:

  • Organization
  • 可重用性
  • 测试
  • 可扩展性
  • 抽象

在 TypeScript 中,函数既可以作为命名函数创建,也可以作为匿名函数创建。

不带参数的命名函数

    function GetFullName(): string
    {
        return "Toufique Rahman Tshovon";
    }
    var Name = GetFullName();
    console.log(Name);

让我们来解释一下代码 GetFullName 是函数名,它没有使用任何参数,返回类型为 string。function 和 return 是关键字。return 关键字返回一个值。

输出: Toufique Rahman Tshovon

带参数的命名函数

function GetFullName(firstName: string, lastName: string): string {
    return firstName + " " + lastName;
}
var Name = GetFullName("Shamim", "Uddin");
console.log(Name);

让我们来解释一下代码 GetFullName 是函数名,它接受两个参数,一个叫 firstName,另一个叫 lastName,两者都是 string 类型。firstName 和 lastName 已连接。

输出: Shamim uddin

不带参数的匿名函数

var Name = function (): string {
    return "Toufique Rahman Tshovon";
}
console.log(Name());

让我们来解释一下代码。没有方法名。但是 Name 变量保存着函数的执行,它没有参数。

输出: Toufique Rahman Tshovon

带参数的匿名函数

var Name = function (firstName: string, lastName: string): string {
    return firstName + " " + lastName;
}
console.log(Name("Shamim", "Uddin"));

让我们来解释一下代码。没有方法名。但是 Name 变量保存着函数的执行,它有两个参数,一个叫 firstName,另一个叫 lastName,两者都是 string 类型。firstName 和 lastName 已连接。

默认参数

function add(firstnumber: number, secondNumber: number=10): number {
    return firstnumber + secondNumber;
}
console.log(add(10));

输出:20

让我们来解释一下代码。我们在 secondNumber 中分配了默认参数。如果不传递 secondNumber,那么默认将分配 10。但是如果我们传递 secondNumber,那么 secondNumber 将被分配,如下所示:

function add(firstnumber: number, secondNumber: number=10): number {
    return firstnumber + secondNumber;
}
console.log(add(10,30));

输出:40

函数重载

函数重载或方法重载能够创建具有不同签名或不同参数的同名多个方法。

开始吧 下面是代码

function Add(firstNumber: number, secondNumber: number)
function Add(firstNumber: number, secondNumber: number, thirdNumber:number)
function Add(firstNumber: number, secondNumber: number, thirdNumber:number, forthNumber: number);

function Add(firstNumber?: number, secondNumber?: number, thirdNumber?: number, forthNumber?: number): number {
    var result = 0;

    if (firstNumber != undefined && secondNumber != undefined && thirdNumber != undefined && forthNumber != undefined) {
        result = firstNumber + secondNumber + thirdNumber + forthNumber;
        
    }
    else if (firstNumber != undefined && secondNumber != undefined && thirdNumber != undefined) {
        result = firstNumber + secondNumber + thirdNumber;
    }
    else if (firstNumber != undefined && secondNumber != undefined) {
        result = firstNumber + secondNumber;
    }
    return result;
}
console.log(Add(1, 2));
console.log(Add(1, 2, 2));
console.log(Add(1, 2, 2, 5));

让我们来解释一下代码

function Add(firstNumber: number, secondNumber: number)

Add 是一个函数,它有两个参数。

function Add(firstNumber: number, secondNumber: number, thirdNumber)

Add 是一个函数,它有三个参数。

function Add(firstNumber: number, secondNumber: number, thirdNumber, forthNumber: number);

Add 是一个函数,它有四个参数。

下面,有三个方法,它们的名称相同,但参数数量不同。

function Add(firstNumber?: number, secondNumber?: number, thirdNumber?: number, forthNumber?: number): number {
    var result = 0;

    if (firstNumber != undefined && secondNumber != undefined && thirdNumber != undefined && forthNumber != undefined) {
        result = firstNumber + secondNumber + thirdNumber + forthNumber;
        
    }
    else if (firstNumber != undefined && secondNumber != undefined && thirdNumber != undefined) {
        result = firstNumber + secondNumber + thirdNumber;
    }
    else if (firstNumber != undefined && secondNumber != undefined) {
        result = firstNumber + secondNumber;
    }
    return result;
}

上面我们实现了我们的方法。result 是一个变量,它默认被赋值为 0,并使用 if else 语句。根据参数调用方法。

类与对象

类是模板,包含属性和方法。它是一种自定义数据类型。类用于

创建无限个对象。

图:类结构

ClassStructure

上面图片中有三个部分。

类名:您需要给类命名。例如-Employee。

属性:您需要定义类的属性。让类名为 Employee。您需要头脑风暴,属性会是什么?例如-1. FirstName。2. LastName。

方法:您需要定义使用这个类可以执行的任务。

例如-1. GetFullName() 2. GetReverseName()

对象:对象是从特定类创建的个体实例。

图:从类创建多个对象

Object

我们可以看到上面的图片。一个 Employee 类和四个 Employee 类的对象。对象可以无限创建,也就是说,当你需要创建对象时,你就可以创建对象。让我们来看看代码。

class Employee {
    // -----start attributes
    public FirstName: string;
    public LastName: string;
     // -----end attributes

    //------start Mehodes
    public GetFullName(): string
    {
        return this.FirstName + " " + this.LastName;
    }
 
    public GetReverseName(): string {
        var fullName = this.GetFullName();        
        var reverse = '';
        for (var i = fullName.length - 1; i >= 0; i--)
            reverse += fullName[i];
        return reverse;
    }
    //------end Mehodes
}
// Onload event,when page load
window.onload = () => {
    var aemployee = new Employee();
    aemployee.FirstName = "Toufique";
    aemployee.LastName = "Rahman";
    var fullName = aemployee.GetFullName();
    var reverseName = aemployee.GetReverseName();
    document.getElementById('fulName').innerHTML = fullName;
    document.getElementById('reverseName').innerHTML = reverseName;
};

让我们来解释一下代码

class Employee

类名 Employee

 public FirstName: string;
 public LastName: string;

这两行是类的属性。

  public GetFullName(): string
    {
        return this.FirstName + " " + this.LastName;
    }
 
    public GetReverseName(): string {
        var fullName = this.GetFullName();        
        var reverse = '';
        for (var i = fullName.length - 1; i >= 0; i--)
            reverse += fullName[i];
        return reverse;
    }

上面代码中有两个方法,一个是 GetFullName(),另一个是 Ger ReverseName()。

 var aemployee = new Employee();

已创建名为 aemployee 的对象。

  aemployee.FirstName = "Toufique";
  aemployee.LastName = "Rahman";

已分配类的属性,即 FirstName 和 LastName。

var fullName = aemployee.GetFullName();
var reverseName = aemployee.GetReverseName();

调用了两个方法并将它们保存在变量中。

 document.getElementById('fulName').innerHTML = fullName;
 document.getElementById('reverseName').innerHTML = reverseName;

这些是简单的 JavaScript 代码,获取 HTML 标签并分配值。

构造函数

构造函数是一种特殊的函数。它在创建类对象时默认调用。

示例:下面是 Employee 类的代码

class Employee {
    public FirstName: string;
    public LastName: string;

    constructor(firstName: string, lastName: string) {
        this.FirstName = firstNmae;
        this.LastName = lastName;
    }

    public GetFullName(): string {
        return this.FirstName + "" + this.LastName;
    }
}

调用 Employee 类

图:创建对象

Untitled

 

让我们来解释一下代码

上面代码中我们看到有一个构造函数,它有两个参数。一个是 firstName,另一个是 lastName。这两个参数都分配给 Employee 类的属性 FirstName 和 LastName。创建 Employee 类的对象:

  var aemployee = new Employee("Toufique", "Rahman");

注意

  • 不允许有多个构造函数实现。
  • 如果类中存在带参数的构造函数,则不传递参数,创建对象是不可能的。

继承

继承是面向对象语言的一种模式,它在不同的类之间建立关系,但具有共同的类型。这种关系称为 IS-A 关系。

图:两个类之间的继承关系

Inheritance

基类

class PermanentEmployee {
     public FirstName: string;
     public LastName: string;

     constructor(firstName: string, lastName: string) {
         this.FirstName = firstName;
         this.LastName = lastName;
     }

     public GetFullName(): string {
         return this.FirstName + " " + this.LastName;
     }

     public GetReverseName(): string {
         var fullName = this.GetFullName();
         var reverse = '';
         for (var i = fullName.length - 1; i >= 0; i--)
             reverse += fullName[i];
         return reverse;
     }
}

子类

class TemporaryEmployee extends PermanentEmployee {

    public JobDuration: string;

    constructor(firstName: string, lastName: string) { super(firstName, lastName); }

}
var employeeObj = new TemporaryEmployee("Toufique", "Rahman");
var fullName = employeeObj.GetFullName();
var reverseName = employeeObj.GetReverseName();

让我们来解释一下代码

这里,基类是 PermanentEmployee。

 class PermanentEmployee {

属性

  public FirstName: string;
  public LastName: string;

构造函数有两个参数。一个是 firstName,另一个是 lastName。两者都分配给属性。

constructor(firstName: string, lastName: string) {
         this.FirstName = firstName;
         this.LastName = lastName;
     }

两个方法,一个是 GetFullName

   public GetFullName(): string {
         return this.FirstName + " " + this.LastName;
     }

另一个是 GetReverseName

public GetReverseName(): string {
         var fullName = this.GetFullName();
         var reverse = '';
         for (var i = fullName.length - 1; i >= 0; i--)
             reverse += fullName[i];
         return reverse;
     }

子类是 TemporaryEmployee。

class TemporaryEmployee extends PermanentEmployee {

这里 TemporaryEmployee 类使用 extends 关键字继承了 PermanentEmployee 类。现在我们可以访问 PermanentEmployee 的属性。

 public JobDuration: string;

构造函数

 constructor(firstName: string, lastName: string) { super(firstName, lastName); }

构造函数接受两个参数。参数值使用 super 关键字分配给基础类的构造函数。创建了 TemporaryEmployee 类的对象。

var employeeObj = new TemporaryEmployee("Toufique", "Rahman");
var fullName = employeeObj.GetFullName();
var reverseName = employeeObj.GetReverseName();

创建了对象 employeeobj,然后为构造函数传递了两个属性。这里有趣的是,我们可以在子类(TemporaryEmployee)中访问 GetFullName 和 GetReverseName。这些是基类(PermanentEmployee)。现在我们可以因为 IS-A 关系而在子类(TemporaryEmployee)中访问它们。

访问修饰符

  • TypeScript 有三种访问修饰符,分别是publicprivateprotected
  • 访问修饰符可防止滥用类成员(函数和属性)。
  • 如果不对任何访问修饰符使用,TypeScript 默认会将 public 访问修饰符设置为所有类成员(函数或属性)。

Public 访问

如果对类成员(函数或属性)使用 public 访问修饰符,则可以在代码中的任何地方自由访问这些成员。例如基类或子类。

示例

让我们来看下面的代码片段解释

class SavingAccount {

    public AccountNo: string;
    private Amount: number;

    constructor(accountNo: string) {
        this.AccountNo = accountNo;
    }
    public Deposit(amount: number): string {
        this.Amount = amount;
        return "Deposit Successfully.";
    }
    public withdraw(amount: number): string {
         this.Amount = amount;
        return "withdraw Successfully.";
    }
    public TotalAmount(): number {
        return this.Amount;
    }
}

var _savingAccount = new SavingAccount("sav0234232");
_savingAccount.Deposit(1000);
_savingAccount.withdraw(500);
_savingAccount.TotalAmount();

类(函数和属性)中的所有 Public 成员都可以通过 SavingAccount 类的对象引用来调用,并且 public 成员总是可以调用子类。

Private 访问:如果对类成员(函数或属性)使用 private 访问修饰符,则只能在类内部由其其他类成员(函数)访问这些成员。

示例

让我们来看下面的代码片段解释

class SavingAccount {

    public AccountNo: string;
    private Amount: number;

    constructor(accountNo: string) {
        this.AccountNo = accountNo;
    }
    public Deposit(amount: number): string {
        this.Amount = amount;
        return "Deposit Successfully.";
    }
    public withdraw(amount: number): string {
         this.Amount = amount;
        return "withdraw Successfully.";
    }
    public TotalAmount(): number {
        return this.Amount;
    }
}

var _savingAccount = new SavingAccount("sav0234232");

当我们调用 Amount 属性,它是一个 private 属性时。然后我们得到一个错误。

privaterror

上面代码中我们可以看到 Amount 属性在 SavingAccount 类中的 TotalAmount 函数中使用。因此,我们可以轻松使用这个 Amount 属性。

protected 访问:如果对类成员(函数或属性)使用 protected 访问修饰符,则可以在子类中访问这些成员。否则,无法访问此访问修饰符。

示例:基类

class Account {

    public AccountNo: string;
    protected Amount: number;

    constructor(accountNo: string) {
        this.AccountNo = accountNo;
    }
    public Deposit(amount: number): string {
        this.Amount = amount;
        return "Deposit Successfully.";
    }
    public withdraw(amount: number): string {
         this.Amount = amount;
        return "withdraw Successfully.";
    }
    protected TotalAmount(): number {
        return this.Amount;
    }
}

当我们使用该类的对象调用该类的 Protected 成员时,我们会得到一个错误。

222222

Protected 类似于 private。

子类

class SavingAccount extends Account
{
    constructor(accountNo: string) { super(accountNo); }

    // Amount propertices is a protected which is base class
    public TotalAmount(): number {
        return this.Amount; 
    }
}

var _savingAccount = new SavingAccount("Sav-43434");
_savingAccount.Deposit(1000);
_savingAccount.withdraw(500);
_savingAccount.TotalAmount();

上面代码中我们可以看到 Amount 属性在 TotalAmount 函数中使用,该函数是 protected 并且存在于基类中。从上面的代码我们知道 protected 成员在子类中使用。否则我们无法使用它。

静态函数与属性

静态函数和属性只能通过它们的类引用调用,而不能通过对象引用调用。有时我们需要避免不必要地创建对象,那时我们就使用 Static。

示例

class Calculator {

    public static FirstNumber: number;
    public static SecondNumber: number;

    public static addTowNumber(): number {
        return this.FirstNumber + this.SecondNumber;
    }
}

Calculator.FirstNumber = 10;
Calculator.SecondNumber = 30;
Calculator.addTowNumber()

让我们来解释一下代码

上面代码中有两个静态属性和一个静态函数。当调用这些属性和函数时,不需要创建对象。它们是通过类名调用的。

例如

Calculator.FirstNumber = 10;
Calculator.SecondNumber = 30;
Calculator.addTowNumber()

接口

Interface 是一种面向对象的语法,用于管理应用程序的美观性。也就是说,类和方法已经准备好了。我们只需调用,就会自己实现这个方法。方法名在整个应用程序中将是相同的。示例: Interface 类

interface iGenericFactory {

    Save(): void;
    Update(): void;
    delete(): void
}

这里没有方法实现。我们可以看到只有方法名和签名。Interface 实现

class Employee implements iGenericFactory 
{
    public Save(): void {
        // Here Save code
    }
    public Update(): void {
        // Here Update code
    }
    public delete(): void {
        // Here Delete code
    }
 
  }

注意

  • 当我们实现 interface 时,必须使用 implements 关键字。
  • 所有方法都将得到实现。

快乐编码 :) 

 

© . All rights reserved.