什么是TypeScript?
TypeScript是JavaScript的超集。TypeScript是一种纯面向对象的编程语言,它可以很容易地在浏览器或NodeJS中运行。
为ECMAScript发布的所有最新功能在TypeScript中都受支持,此外,TypeScript还具有自己的面向对象的功能,如接口、环境声明、类继承等,这有助于开发大型应用程序,否则在JavaScript中很难做到这一点。
在这份面向初学者的简单易学的TypeScript教程中,我们将介绍以下主题:
- 如何下载和安装TypeScript
- TypeScript的变量
- TypeScript中的类型
- 什么是数组?
- TypeScript数组方法
- 在TypeScript中定义类
- 排版中的访问修饰符
- TypeScript中的接口
- TypeScript中的功能
- 什么是枚举?
- TypeScript中的模块是什么?
- TypeScript中的命名空间
- TypeScript脚本中的环境声明
- TypeScript历史记录
- 为什么要用TypeScript呢?
- 谁用TypeScript?
如何下载和安装TypeScript:
我们将通过首先安装它来学习TypeScript 。 进入nodejs:https://nodejs.org/en/download/官网,根据操作系统下载并安装nodejs。有要检查是否安装了NodeJS和NPM,只需在命令提示符中检查版本即可。
因此,已经安装了NodeJSV10和NPM6。
TypeScript脚本安装
创建项目目录typeproject/并运行npm init,如以下命令所示:
在本TypeScript教程中,我们将创建.json包,它将存储我们项目的依赖项。
完成后,按如下方式安装TypeScript:
上面的命令将负责安装TypeScript。如果不想全局安装TypeScript,使用以下命令:
在项目目录和src/文件夹中创建src/文件夹,创建类型脚本文件test.ts并编写代码。
示例:test.ts
将TypeScript代码编译为Javascript
要编译上述代码,使用以下命令:
如果全局安装了TypeScript,使用以下命令:
如果项目本地安装了TypeScript,则需要使用NODE_MODULES中的TypeScript路径,如下所示:
上述命令将创建一个test.js文件,并将代码编译为javascript。
示例:test.js
使用NodeJS执行Javascript
在本TypeScript教程中,我们将在NodeJS中执行test.js,如下所示:
在执行test.js时会显示Consoled的值
在浏览器中执行JavaScript
示例:
<html>
<head>
</head>
<body>
<script src="/test.js" type="text/javascript">
</script>
</body>
</html>
使用ECMAScript版本将TypeScript代码编译为Javascript
TypeScript支持发布的所有ECMAScript特性,开发人员可以在编码时使用这些特性。但并不是所有的新特性su tyescript都提供了可以这样做的编译器选项。
示例:test.ts
要编译到选择的ES版本,可以在命令中使用target或t选项,如下所示:
默认情况下,目标是ES3。如果想要更改它,可以使用上面的命令。
目前,我们将在本TypeScript教程中使用ES6作为目标:
test.ts到test.js
代码保持原样,因使用的箭头函数是ES6特性,编译为ES6时也没有更改。
默认情况下,目标是ES3,因此没有目标,得到的test.js为:
所以在这里,胖箭头变成了一个普通的匿名函数。
TypeScript中的变量
变量用于存储值,值可以是字符串、数字、布尔值或表达式。当涉及到TypeScript中的变量时,它们类似于JavaScript。因此,让我们学习如何在TypeScript中声明变量并为其赋值。
在没有定义的情况下,不能在代码中使用变量。要声明一个变量,可以使用
var关键字,
let关键字
const关键字
在tyescript中使用变量类似于javascript,熟悉javascript的用户会发现这非常容易。与var相比,只有let和const这样的变量使用得不多。
使用var声明变量
语法:
让我们看几个TypeScript示例,以了解var关键字的工作原理以及使用var关键字声明的变量的范围。
示例1:
var k = 1; // variable k will have a global scope
function test() {
var c = 1; // variable c is local variable and will be accessible inside function test, it will not be available outside the function.
return k++;
}
test(); // output as 1
test(); // output as 2
alert(c); // will throw error , Uncaught ReferenceError: c is not defined
示例2:
var t = 0; // variable t is declared in global scope.
function test() {
var t = 10; //variable t is again redeclared inside function with value 10, so here t is local to the function and changes done to it will remain inside the function.
return t;
}
test(); // will return 10.
console.log(t); // will console 0.
示例3:
var i = 0;
function test() {
if (i < 0) {
var t = 1;
}
return t;
}
test(); // the value returned will be undefined. The if-block has the variable which gets executed when i < 0. Over here the if-block is not expected but you are still having a reference to the variable t, and it returns undefined, this is because var defined variables once defined inside a function will have reference to it inside the function.
i++; // here value of i is incremented.
test(); // since i < 0 the if block is executed and value returned is 1.
使用let声明变量
let的TypeScript脚本语法如下所示:
语法:
let变量的工作方式与var几乎相同,但略有不同,使用TypeScript脚本示例将会理解相同的内容。
示例:
let i = 1;
function test() {
if (i < 0) {
let t = 1;
}
return t;
}
test(); // throws an error : Uncaught ReferenceError: t is not defined.
上面的TypeScript示例抛出了一个错误,但是如果使用var关键字,同样可以很好地工作。使用let的变量在声明的挡路范围内可用,例如,变量t仅在if-挡路内可用,而不能用于整个函数。
此外,如果碰巧在任何函数或for循环、While循环、TypeScript开关挡路内声明了一个变量,则该变量将仅在该挡路内可用,而不能在挡路外部引用它,如果该变量在挡路之外使用,则会抛出一个错误。这是var和let关键字声明的变量之间的主要区别。
使用const声明变量
常量表示常量变量。它们类似于let变量,唯一的区别是,一旦为其赋值,就不能更改。
语法:
示例:
const age = "25";
age="30"; // will throw an error : Uncaught TypeError: Assignment to constant variable.
因此,用户只有在知道不必更改分配给它的值的情况下才能使用常量变量。
TypeScript中的类型
TypeScript是一种强类型语言,而javascript不是。一个变量的值被定义为在TypeScript中,变量的类型只在开始时定义,并且在执行过程中,它必须保持相同的类型,对它的任何更改都将在编译到javascript期间导致编译时错误。
以下是类型:
- 数
- 字符串
- 布尔值
- Any
- void
数字:
将只接受整数、浮点数、小数等。 语法:
以下是可用于数字类型的一些重要方法:
toFixed() -它会将数字转换为字符串,并保留给该方法的小数位。
toString() -此方法将数字转换为字符串。
valueOf() -此方法将返回数字的原始值。
toPrecision() -此方法将数字格式化为指定长度。
示例:使用所有字符串方法
let _num :number = 10.345;
_num.toFixed(2); // "10.35"
_num.valueOf(); // 10.345
_num.toString(); // "10.345"
_num.toPrecision(2); //"10"
字符串
字符串:仅字符串值
语法:
以下是可用于字符串类型的一些重要方法:
- split()-此方法将字符串拆分成数组。
- charat()-此方法将给出给定索引的第一个字符。
- indexOf()-此方法将给出赋给它的值的第一个匹配项的位置。
- replace()-此方法接受2个字符串,第一个是要在字符串中搜索的值,如果存在,将替换第二个字符串,并返回一个新字符串。
- trim()-此方法将删除字符串两边的空格。
- substr()-此方法将给出字符串的一部分,这取决于作为start和end给定的位置。
- substring()-此方法将给出字符串的一部分,这取决于作为开始和结束给定的位置。末尾位置的字符将被排除。
- toUpperCase()-将字符串转换为大写
- toLowerCase()-将字符串转换为小写。
示例:
let _str:string = "Typescript";
_str.charAt(1); // y
_str.split(""); //["T", "y", "p", "e", "s", "c", "r", "i", "p", "t"]
_str.indexOf("s"); //4 , gives -1 is the value does not exist in the string.
_str.replace("Type", "Coffee"); //"Coffeescript"
_str.trim(); //"Typescript"
_str.substr(4, _str.length); //"script"
_str.substring(4, 10); //"script"
_str.toUpperCase();//"TYPESCRIPT"
_str.toLowerCase();//"typescript"
布尔值
将接受逻辑值,如TRUE、FALSE、0和1。
语法:
any
语法:
使用任何类型声明的变量可以接受字符串、数字、数组、布尔值或void形式的变量。仅当不确定将与任何类型变量关联的值的类型时,才使用该类型变量。
void
void类型主要用作函数的返回类型,该函数没有任何要返回的内容。
语法:
字体数组
TypeScript中的数组是一种可以存储多个值的数据类型。让我们学习如何在TypeScript中声明和赋值给Array操作。
由于TypeScript是一种强类型语言,因此必须知道数组中的值的数据类型是什么。否则,它会将其视为Any类型。
声明和初始化数组
语法:
示例
let months: Array
<string>
= ["Jan", "Feb", "March", "April", "May", "June", "July", "Aug", "Sept", "Oct", "Nov", "Dec"]; //array with all string values.
let years: Array
<number>
= [2015, 2016, 2017, 2018, 2019]; //array will all numbers
let month_year: Array
<string number="" |="">
= ["Jan", 2015, "Feb", 2016]; //array with string and numbers mixed.
let alltypes: Array
<any>
= [true, false, "Harry", 2000, { "a": "50", "b": "20" }]; //array of all types boolean, string , number , object etc.
</any>
</string>
</number>
</string>
从数组访问元素的不同方式
要从数组中获取元素,这些值从索引0开始,一直到数组的长度。
示例:
let years: Array
<number>
= [ 2016, 2017, 2018, 2019]; //array will all numbers
years[0]; // output will be 2016
years[1]; // output will be 2017
years[2]; // output will be 2018
years[3]; // output will be 2019
</number>
还可以使用TypeScript for循环从数组中获取元素,如下所示:
使用TypeScript for循环
let years: Array
<number>
= [ 2016, 2017, 2018, 2019];
for (let i=0;i<=years.length; i++) {
console.log(years[i]);
}
Output:
2016
2017
2018
2019
</number>
使用for-in循环
let years: Array
<number>
= [ 2016, 2017, 2018, 2019];
for (let i in years) {
console.log(years[i])
}
Output:
2016
2017
2018
2019
</number>
使用for-of循环
let years: Array
<number>
= [ 2016, 2017, 2018, 2019];
for (let i of years) {
console.log(i)
}
Output:
2016
2017
2018
2019
</number>
使用foreach循环
let years: Array
<number>
= [ 2016, 2017, 2018, 2019];
years.forEach(function(yrs, i) {
console.log(yrs);
});
Output:
2016
2017
2018
2019
</number>
TypeScript数组方法
TypeScript Array对象有许多属性和方法,可以帮助开发人员轻松高效地处理数组。可以通过指定arrayname.property来获取属性的值,并通过指定数组 name.method() 来获取方法的输出。
length属性
=>如果想知道数组中元素的数量,可以使用Length属性。
reverse法
=>可以使用reverse方法来反转数组中项目的顺序。
sort方法
=>可以使用sort方法对数组中的项进行排序。
pop方法
=>可以使用pop方法删除数组的最后一项。
shift方法
=>可以使用shift方法删除数组的第一项。
push方法
=>可以将值添加为数组的最后一项。
concat方法
=>可以将两个数组合并为一个数组元素。
length属性的示例
let months: Array
<string>
= ["Jan", "Feb", "March", "April", "May", "June", "July", "Aug", "Sept", "Oct", "Nov", "Dec"]; //array with all string values.
console.log(months.length); // 12
</string>
reverse方法示例:
let months: Array
<string>
= ["Jan", "Feb", "March", "April", "May", "June", "July", "Aug", "Sept", "Oct", "Nov", "Dec"]; //array with all string values.
console.log(months.reverse()); // ["Dec", "Nov", "Oct", "Sept", "Aug", "July", "June", "May", "April", "March", "Feb", "Jan"]
</string>
sort方法的示例:
let months: Array
<string>
= ["Jan", "Feb", "March", "April", "May", "June", "July", "Aug", "Sept", "Oct", "Nov", "Dec"]; //array with all string values.
console.log(months.sort()); // ["April", "Aug", "Dec", "Feb", "Jan", "July", "June", "March", "May", "Nov", "Oct", "Sept"]
</string>
pop方法示例:
let months: Array
<string>
= ["Jan", "Feb", "March", "April", "May", "June", "July", "Aug", "Sept", "Oct", "Nov", "Dec"]; //array with all string values.
console.log(months.pop()); //Dec
</string>
shift方法示例:
let months: Array
<string>
= ["Jan", "Feb", "March", "April", "May", "June", "July", "Aug", "Sept", "Oct", "Nov", "Dec"]; //array with all string values.
console.log(months.shift()); // Jan
</string>
push方法示例:
let years: Array
<number>
= [2015, 2016, 2017, 2018, 2019]; //array will all numbers
console.log(years.push(2020));
years.forEach(function(yrs, i) {
console.log(yrs); // 2015 , 2016,2017, 2018, 2019,2020
});
</number>
concat方法示例:
let array1: Array
<number>
= [10, 20, 30];
let array2: Array
<number>
= [100, 200, 300];
console.log(array1.concat(array2)); //[10, 20, 30, 100, 200, 300]
</number>
</number>
在TypeScript中定义类
TypeScript是JavaScript的超集,因此在JavaScript中可以做的任何事情在TypeScript中也是可能的。类是ES6从ES6开始添加的一个新特性,所以我之前在TypeScript/JavaScript中使用了类的特性,它使语言变得非常强大。
以下是TypeScript中的基本类语法:
class nameofclass {
//define your properties here
constructor() {
// initialize your properties here
}
//define methods for class
}
示例:课堂上的一个工作示例
class Students {
age : number;
name : string;
roll_no : number;
constructor(age: number, name:string, roll_no: number) {
this.age = age;
this.name = name;
this.roll_no = roll_no;
}
getRollNo(): number {
return this.roll_no;
}
getName() : string {
return this.name;
}
getAge() : number {
return this.age;
}
}
在上面的示例中,有一个名为Students的类。它具有属性age、name和roll_no。
TypeScript类中的构造函数
我们在上面定义的类学生示例,它有一个构造函数,如下所示:
constructor(age: number, name:string, roll_no: number) {
this.age = age;
this.name = name;
this.roll_no = roll_no;
}
构造函数方法有参数age、name和roll_no。构造函数会注意也可以有一个默认的构造函数,如下所示:
TypeScript类中的方法
类学生示例有定义的方法,例如 getRollNo() 、getName()、getAge(),这些方法用于提供属性roll_no、name和age的详细信息。
getRollNo(): number {
return this.roll_no;
}
getName() : string {
return this.name;
}
getAge() : number {
return this.age;
}
在打印脚本中创建类的实例
在TypeScript中,要创建类的实例,需要使用new运算符。当我们使用new操作符创建类的实例时,我们将获得可以访问类的属性和方法的对象,如下所示:
let student_details = new Students(15, "Harry John", 33);
student_details.getAge(); // 15
student_details.getName(); // Harry John
将TypeScript类编译为JavaScript
可以使用如下所示的TSC命令编译为Javascript。
命令:TSC Students.ts
编译时的Javascript代码输出如下所示:
var Students = /@class */ (function () {
function Students(age, name, roll_no) {
this.age = age;
this.name = name;
this.roll_no = roll_no;
}
Students.prototype.getRollNo = function () {
return this.roll_no;
};
Students.prototype.getName = function () {
return this.name;
};
Students.prototype.getAge = function () {
return this.age;
};
return Students;
}());
在Javascript中,类被转换为自调用函数。
类继承
可以在TypeScript中使用EXTEND关键字继承类。
类继承语法:
class A {
//define your properties here
constructor() {
// initialize your properties here
}
//define methods for class
}
class B extends A {
//define your properties here
constructor() {
// initialize your properties here
}
//define methods for class
}
B类将能够共享A类方法和属性。
下面是一个使用继承的类的工作示例
class Person {
name: string;
age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
getName(): string {
return this.name;
}
getAge(): number {
return this.age;
}
}
class Student extends Person {
tmarks: number;
getMarks(): number {
return this.tmarks;
}
setMarks(tmarks) {
this.tmarks = tmarks;
}
}
let _std1 = new Student('Sheena', 24);
_std1.getAge(); // output is 24
_std1.setMarks(500);
_std1.getMarks(); // output is 500
有两个类,个人类和学生类。学生类扩展了Person,在Student上创建的对象能够访问它自己的方法和属性以及它扩展的类。
现在,让我们对上面的类进行更多的更改。
示例:
class Person {
name: string;
age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
getName(): string {
return this.name;
}
getAge(): number {
return this.age;
}
}
class Student extends Person {
tmarks: number;
constructor(name: string, age: number, tmarks: number) {
super(name, age);
}
getMarks(): number {
return this.tmarks;
}
setMarks(tmarks) {
this.tmarks = tmarks;
}
}
let _std1 = new Student('Sheena', 24, 500);
_std1.getAge(); // output is 24
_std1.getMarks(); // output is 500
与前一个示例相比,添加的更改是在类Student中定义了一个构造函数。构造函数必须采用与基类相同的参数,并添加其自身的任何其他参数(如果有的话)。
在TypeScript中,需要调用superwill,将所有参数作为其中的基本参数。超级将执行扩展类的构造函数。
访问修饰符
TypeScript支持方法和属性的公共、私有和受保护访问修饰符。默认情况下,如果没有给出访问修饰符,则该方法或属性被认为是公共的,并且可以很容易地从类的对象访问它们。
对于私有访问修饰符,它们不能从类的对象访问,只能在类内部使用。它们不可用于继承的类。
对于受保护的访问修饰符,它们应该在类和继承的类中使用,并且不能从类的对象访问。
示例:
class Person {
protected name: string;
protected age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
private getName(): string {
return this.name;
}
getDetails(): string {
return "Name is "+ this.getName();
}
}
class Student extends Person {
tmarks: number;
constructor(name: string, age: number, tmarks: number) {
super(name, age);
this.tmarks = tmarks;
}
getMarks(): number {
return this.tmarks;
}
getFullName(): string {
return this.name;
}
setMarks(tmarks) {
this.tmarks = tmarks;
}
}
let _std1 = new Student('Sheena', 24, 500);
_std1.getMarks(); // output is 500
_std1.getFullName(); // output is Sheena
_std1.getDetails(); // output is Name is Sheena
- 私有属性或方法不能由类的对象访问,也不能由派生类访问,它们应该在类内部使用。
- 创建的对象也无法访问受保护的属性和方法。它们可以从类内部访问,并且可供扩展它的类使用。
- 公共属性和方法是在没有任何关键字的情况下声明的。可以使用类的对象从外部轻松访问它们。
TypeScript界面
TypeScript的核心功能之一是界面。该接口是一组定义的规则,该接口为实现该接口的任何函数、变量或类添加了强类型检查。
TypeScript中接口的语法:
已经定义了一个名为Dimension的接口,该接口具有属性Width和Height,并且这两个属性的类型都是字符串。
现在,该接口可以由变量、函数或类实现。以下是变量实现接口维度的示例。
示例:
interface Dimension {
width: string;
height: string;
}
let _imagedim: Dimension = {
width: "100px",
height: "200px"
};
界面维度签名有宽度和高度,均为必填项。如果在实现接口时遗漏了任何属性,或者更改了类型,则在将代码编译为javascript时会给出编译时错误。
当编译成javascript时,上面的代码如下所示:
现在让我们看看如何将接口与函数一起使用。
将函数上的接口用作返回类型
示例:
interface Dimension {
width: string;
height: string;
}
function getDimension() : Dimension {
let width = "300px";
let height = "250px";
return {
width: width,
height: height
}
}
在上面的示例中,接口维度作为返回类型在函数 getDimension() 上实现。 getDimension() 的返回类型必须与接口维度中提到的属性和类型匹配。
编译为Javascript的代码如下所示:
function getDimension() {
var width = "300px";
var height = "250px";
return {
width: width,
height: height
};
}
在编译过程中,如果返回类型与接口不匹配,则会抛出错误。
接口作为函数参数
interface Dimension {
width: string;
height: string;
}
function getDimension(dim: Dimension) : string {
let finaldim = dim.width +"-"+ dim.height;
return finaldim;
}
getDimension({width:"300px", height:"250px"}); // will get "300px-250px"
因此,在上面的示例中,使用了Interface Dimension作为函数 getDimension() 的参数。调用函数时,需要确保传递给它的参数与定义的接口规则匹配。
编译为Javascript的代码如下所示:
function getDimension(dim) {
var finaldim = dim.width + "-" + dim.height;
return finaldim;
}
getDimension({ width: "300px", height: "250px" });
类实现接口
要使用与类的接口,需要使用关键字Implementes。
实现接口的类的语法:
下面的示例显示了接口与类的工作方式。
interface Dimension {
width : string,
height: string,
getWidth(): string;
}
class Shapes implements Dimension {
width: string;
height: string;
constructor (width:string, height:string) {
this.width = width;
this.height = height;
}
getWidth() {
return this.width;
}
}
在上面的示例中,定义了接口Dimension,其属性Width和Height均为String类型,并定义了一个名为 getWidth() 的方法,该方法的返回值为字符串。
编译为Javascript的代码如下所示:
var Shapes = /@class */ (function () {
function Shapes(width, height) {
this.width = width;
this.height = height;
}
Shapes.prototype.getWidth = function () {
return this.width;
};
return Shapes;
}());
TypeScript中的功能
功能是为执行任务而执行的一组指令。在Javascript中,javascript中的函数与tyescript函数的最大区别在于tyescript函数提供的返回类型。
JavaScript函数:
TypeScript函数:
在上述函数中,添加了函数名,参数为a1,b1的类型均为Number,返回类型也为Number。如果碰巧将字符串传递给函数,则在将其编译为JavaScript时,它将抛出编译时错误。
调用函数:Add
let x = add(5, 10) ; // will return 15
let b = add(5); // will throw an error : error TS2554: Expected 2 arguments, but got 1.
let c = add(3,4,5); // will throw an error : error TS2554: Expected 2 arguments, but got 3.
let t = add("Harry", "John");// will throw an error : error TS2345: Argument of type '"Harry"' is not assignable to parameter of type 'number'.
参数a1和b1是强制参数,如果没有以该方式接收,将抛出错误。另外,参数类型和返回类型非常重要,一旦定义就不能更改。
函数的可选参数
在javascript中,函数的所有参数都是可选的,如果没有传递,则被认为是未定义的。但是TypeScript并非如此,一旦定义了参数,也需要发送它们,但是如果想保留任何可选的参数,可以使用?与参数名称对应,如下所示:
function getName(firstname: string, lastname?: string): string {
return firstname + lastname;
}
let a = getName("John"); // will return Johnundefined.
let b = getName("John", "Harry"); // will return JohnHarry
let c = getName("John", "H", "Harry"); // error TS2554: Expected 1-2 arguments, but got 3.
注意,可选参数只能在函数的末尾定义,不能将第一个参数作为可选参数,而将第二个参数作为强制参数。当使用一个参数编译器调用函数时,将抛出错误。因此,有必要将可选参数保留在末尾。
为参数指定默认值
可以为params指定默认值,如下所示:
function getName(firstname: string, lastname = "Harry"): string {
return firstname + lastname;
}
let a = getName("John"); // will return JohnHarry
let b = getName("John", "H"); // will return JohnH
与可选参数类似,这里默认的初始化参数也必须保留在函数的末尾。
Sleep参数
已经看到了TypeScript如何处理强制参数、可选参数和默认值初始化参数。sleep参数是一组一起定义的可选参数,它们使用三个点(…)定义后跟参数的名称,它是一个数组。
睡觉参数语法:
如上所示,Sleep参数是使用(…)定义的param-name);可以调用该函数,如下例所示:
示例:
箭头函数
箭头功能是ES6中发布的重要功能之一,在打印脚本中也提供了该功能。箭头函数语法中有一个胖箭头,因此该函数被称为箭头函数。
箭头函数语法:
箭头功能有什么用途?
让我们看一下示例,了解一下Arrow函数的用例:
示例:
var ScoreCard = function () {
this.score = 0;
this.getScore = function() {
setTimeout(function() {
console.log(this.score); // gives undefined.
}, 1000);
}
}
var a = new ScoreCard();
a.getScore();
已经创建了一个匿名函数,该函数具有属性This。Score初始化为0,在setTimeout内对函数进行int的方法getScore有它自己的this,它尝试在内部引用分数,因为它没有定义,所以给出了unfinded。
可以使用如下所示的箭头函数来处理相同的问题:
var ScoreCard = function () {
this.score = 0;
this.getScore = function () {
setTimeout(()=>{
console.log(this.score); // you get 0
}, 1000);
}
}
var a = new ScoreCard();
a.getScore();
已经将setTimeout内的函数更改为箭头函数,如下所示:
箭头函数没有自己定义的this,并且它共享其父this,因此在箭头函数内使用this可以很容易地访问在外部声明的变量。它们非常有用,因为它们的语法较短,而且对于回调、事件处理程序、内部计时函数等也很有用。
TypeScript枚举
TypeScript Enum是一个对象,它有一组存储在一起的相关值。大多数编程语言,如Java、C、C++都支持TypeScript Enum,也支持TypeScript。枚举是使用关键字枚举定义的。
如何声明枚举?
语法:
示例:枚举
在上面的示例中,定义了一个名为Directions的枚举。对于枚举中的第一个值,这些值从0开始编号,随后为下一个值递增1。
使用数值声明枚举
默认情况下,如果没有为枚举指定任何值,它会将其视为从0开始的数字。下面的示例显示了一个具有数值的枚举。
还可以为枚举分配一个起始值,下一个枚举值将获得递增的值。例如:
现在枚举值North从5开始,因此South将获得值6,East=7,West=8。
也可以指定选择的值,而不是采用默认值。例如:
如何访问枚举?
下面的示例说明如何在代码中使用Enum:
enum Directions {
North,
South,
East,
West
}
console.log(Directions.North); // output is 0
console.log(Directions["North"]); // output is 0
console.log(Directions[0]); //output is North
编译成javascript的代码如下:
var Directions;
(function (Directions) {
Directions[Directions["North"] = 0] = "North";
Directions[Directions["South"] = 1] = "South";
Directions[Directions["East"] = 2] = "East";
Directions[Directions["West"] = 3] = "West";
})(Directions || (Directions = {}));
console.log(Directions.North);
console.log(Directions["North"]);
console.log(Directions[0]);
由于Javascript不支持枚举,因此它将枚举转换为自调用函数,如上所示。
使用字符串值声明枚举
可以指定选择的字符串值,如下例所示:
示例:
enum Directions {
North = "N",
South = "S",
East = "E",
West = "W"
}
console.log(Directions.North); // output is N
console.log(Directions["North"]); // output is N
console.log(Directions[0]); // output is North
编译成javascript的代码如下:
var Directions;
(function (Directions) {
Directions["North"] = "N";
Directions["South"] = "S";
Directions["East"] = "E";
Directions["West"] = "W";
})(Directions || (Directions = {}));
console.log(Directions.North);
console.log(Directions["North"]);
console.log(Directions[0]);
TypeScript中的模块是什么?
在TypeScript中创建的文件具有全局访问权限,这意味着在一个文件中声明的变量可以在另一个文件中轻松访问。此功能在ES6版本的JavaScript中可用,在TypeScript中也受支持。
为什么TypeScript中需要模块?
以下示例显示了不带模块的问题:
示例test1.ts
已经在test1.ts中定义了类型为Number的变量年龄。
示例test2.ts
在test2.ts文件中,可以轻松地访问test1.ts中定义的变量age,还可以对其进行修改,如下所示:
因此,上面的情况可能会产生很多问题,因为变量是全局可用的,并且可以修改。
使用模块时,编写的代码仍保留文件的区域设置,不能在该文件之外进行访问。这样做,编写的代码在文件中保持不变,即使定义了相同的变量名,它们也不会混淆,并且在声明它们的文件中表现为本地行为。
使用导出和导入
出口和进口的方式有很多种。所以在这里我们将讨论使用最多的语法。
导入和导出1的语法:
export nameofthevariable or class name or interface name etc
//To import above variable or class name or interface you have to use import as shown below:
Import {nameof thevariable or class name or interfacename} from "file path here without.ts"
以下是使用导出和导入的工作示例。
示例:
test1.ts
导出关键字用于共享其他文件中的年龄变量。
test2.ts
IMPORT关键字用于访问AGE变量,需要指定如上所示的文件位置。
导入和导出的语法2:
导出和导入还有另一种方式,其语法如下所示:
当使用EXPORT=导出模块时,导入必须使用 require(“file path of modulename”) 来导入。
以下是一个显示上述情况的工作示例:
Customer.ts
class Customer {
name: string;
age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
getName(): string {
return this.name;
}
}
export = Customer;
testCustomer.ts
模块加载器
模块不能单独工作,因此需要模块加载器来定位导入依赖项,如在上面的输入脚本示例中所见。可用的模块加载器是CommonJS,用于NodeJS和Require.js以在浏览器中运行。
要使用CommonJS模块编译代码,使用以下命令:
要使用Requirejs模块编译代码,使用以下命令:
依赖文件将使用上述命令转换为js文件。
使用Requirejs将testCustomer.ts示例为testCustomer.js
define(["require", "exports", "./Customer"], function (require, exports, Customer) {
"use strict";
exports.__esModule = true;
var a = new Customer("Harry", 30);
alert(a.getName());
});
使用Requirejs将Customer.ts转换为Customer.js的示例
define(["require", "exports"], function (require, exports) {
"use strict";
var Customer = /@class */ (function () {
function Customer(name, age) {
this.name = name;
this.age = age;
}
Customer.prototype.getName = function () {
return this.name;
};
return Customer;
}());
return Customer;
});
要使用quire.js对其进行测试,需要创建一个名为main.js的文件,该文件引用了如下所示的依赖项。
以下是文件夹结构:
src/
Customer.js
testCustomer.js
main.js
require.js // you can get this file from github or npm install requirejs
test.html
main.js
define(function (require) {
var customer = require("./Customer");
var testCustomer = require("./testCustomer");
});
test.html
<!DOCTYPE html>
<html>
<head>
<title>
TypeScript Module testing using Requirejs
</title>
<script data-main="main" src="/require.js">
</script>
</head>
<body>
<h3>
Testing modules using Requirejs
</h3>
</body>
</html>
TypeScript中的命名空间
命名空间基本上是将类、接口、变量、函数集合在一个文件中。
命名空间语法:
相关代码在一个命名空间下可用。
命名空间工作示例:testnampace.ts
namespace StudentSetup {
export interface StudDetails {
name: string;
age: number;
}
export function addSpace(str) { // will add space to the string given
return str.split("").join(" ");
}
export class Student implements StudDetails {
name: string;
age: number;
constructor(studentdetails: StudDetails) {
this.name = studentdetails.name;
this.age = studentdetails.age;
}
getName(): string {
return this.name;
}
}
}
名称空间的名称是StudentSetup,已经添加了一个接口StudDetails、函数addSpace和一个名为Student的类。
访问命名空间
以下是使用命名空间StudentSetup的代码。
testStudentSetup.ts
let a = new StudentSetup.Student({ name: "Harry", age: 20 });
console.log("The name is :" + StudentSetup.addSpace(a.getName()));
必须使用命名空间示例StudentSetup.addSpace的名称引用命名空间内可用的类、接口和函数,才能访问函数StudentSetup.Student才能访问该类。
可以将两个文件编译成一个js,如下所示:
使用以下命令检查命令提示符中的输出:
它将输出显示为:
TypeScript脚本中的环境声明
TypeScript允许使用使用环境声明的第三方javascript文件。此功能的优势在于,无需重写,即可在TypeScript中使用库的所有功能。
环境语法
要声明环境模块,执行以下操作:
环境文件必须另存为:
要在.ts中使用文件filename.d.ts,需要将其引用为:
TypeScript中的环境类型声明将引用第三方库,并将使用自己的类型重新声明所需的函数。例如,假设有一个小的javascript库,如下所示:
第三方JavaScript文件:testString.js
示例:testString.js
var StringChecks = {
isString: function (str) {
return typeof str === "string";
},
convertToUpperCase: function (str) {
return str.toUpperCase();
},
convertToLowerCase: function (str) {
return str.toLowerCase();
},
convertToStringBold: function (str) {
return str.bold();
}
};
有一个名为StringChecks的对象,它具有isString、ConvertToUpperCase、ConvertToLowerCase和ConvertToStringBold等函数。
TypeScript中环境模块的创建
现在将创建一个引用上述js函数的环境模块,并根据我们的要求添加类型检查。
文件名:tstring.d.ts
declare module TestString {
export interface StringsFunc {
isString(str: string): boolean;
convertToUpperCase(str: string): string;
convertToLowerCase(str: string): string;
convertToStringBold(str: string): string;
}
}
declare var StringChecks: TestString.StringsFunc;
必须将模块名称定义为TestString,并且已导出接口StringsFunc。
isString(str: string) :布尔值
=>这将把param作为字符串,返回类型为boolean。在.ts文件中使用时,以防碰巧将参数作为数字或字符串以外的任何形式传递,它会给出编译类型错误。
convertToUpperCase(str:string) :字符串
=>这会将参数作为字符串并返回字符串。 convertToLowerCase(str: string) 也是如此:String;和 convertToStringBold(str: string) :String;
由于在javascript文件中对象名为StringChecks,最后我们需要在.d.ts文件中引用相同的名称,具体操作如下:
在TypeScript中使用环境模块
下面是test.ts文件,其中将使用环境文件tstring.d.ts
示例:test.ts
///
<reference path="tstring.d.ts">
</reference>
let str1 = StringChecks.isString("Hello World");
console.log(str1);
let str2 = StringChecks.convertToUpperCase("hello world");
console.log(str2);
let str3 = StringChecks.convertToLowerCase("HELLO");
console.log(str3);
let str4 = StringChecks.convertToStringBold("Hello World");
console.log(str4);
将TypeScript TSC test.ts编译为test.js
///
<reference path="tstring.d.ts">
</reference>
var str1 = StringChecks.isString("Hello World");
console.log(str1);
var str2 = StringChecks.convertToUpperCase("hello world");
console.log(str2);
var str3 = StringChecks.convertToLowerCase("HELLO");
console.log(str3);
var str4 = StringChecks.convertToStringBold("Hello World");
console.log(str4);
现在,可以在html文件中使用test.js,也可以在库文件testString.js中使用
<html>
<head>
<title>
Test TypeScript Ambient
</title>
<script src="/testStrings.js">
</script>
<script src="/test.js">
</script>
</head>
<body>
</body>
</html>
以下是控制台中显示的输出:
TypeScript历史记录
让我们看看TypeScript历史上的重要里程碑:
- 在微软进行了两年的内部开发之后。TypeScript0.9,发布于2013年
- 在Build 2014发布了对泛型Tyescript 1.0的额外支持
- 2014年7月,一个新的TypeScript编译器问世,它的速度比之前的版本快了五倍。
- 2015年7月,支持ES6模块,命名空间关键字,支持装饰符。
- 2016年11月,增加了映射类型的键和查找类型,以及睡觉等功能。
- 2018年3月27日,条件类型,TypeScript中增加了带交叉点类型的改进键支持。
为什么要用TypeScript呢?
以下是使用TypeScript的重要优点/好处
- JavaScript中的大型复杂项目很难编码和维护。
- TypeScript在代码组织方面有很大帮助,而且在编译过程中消除了大部分错误。
- TypeScript支持JS库和API文档
- 它是可选的类型化脚本语言
- 可以将TypeScript代码转换为纯JavaScript代码
- 更好的代码结构和面向对象编程技术
- 允许更好的开发时间工具支持
- 它可以将语言扩展到标准装饰符之外,异步/等待
谁用TypeScript?
以下是TypeScript的一些最常见的应用:
- 棱角分明的团队使用TypeScript。
- NodeJS和NPM安装
- TypeScript脚本安装
- 将TypeScript代码编译为Javascript
- 使用NodeJS执行代码
- 在浏览器中执行Javascript
- 使用ECMAScript版本将TypeScript代码编译为Javascript
- 可以使用NodeJS轻松地将用TypeScript编写的代码编译成JavaScript。
- 因此,要使用TypeScript,需要首先下载并安装NodeJS。