TypeScript是JavaScript类型的超集,它可以编译成纯JavaScript。
TypeScript可以在任何浏览器、任何计算机和任何操作系统上运行,并且是开源的。
TypeScript是微软开源的,它有这强大的技术后盾。
基础类型
TypeScript作为JavaScript的超集,它具有更规范化的数据数据类型,不再像JavaScript一样。它更像Java这样的语言一样。
布尔值
最基本的数据类型就是简单的true/false值
let isDone: boolean = false;
数字
和JavaScript一样,TypeScript里的所有数字都是浮点数。这些浮点数的类型是 number
。除了支持十进制和十六进制,TypeScript还支持ECMAScript中引入的二进制和八进制。
let decLiteral: number = 6; // 十进制
let hexLiteral: number = 0xf00d; // 十六进制
let binaryLiteral: number = 0b1010; // 二进制
let octalLiteral: number = 0o744; // 八进制
字符串
在TypeScript中使用string表示文本数据类型。和JavaScript一样,可以使用双引号(“)或单引号(‘)表示字符串。
let name: string = 'bob'; // 个人推荐使用单引号
name = 'smith';
还可以使用模本字符串,它可以定义多行文本和内嵌表达式。
let name: string = `Gene`;
let age: number = 27;
let sentence: string = `Hello, my name is ${name}.
I'll be ${age + 1} years old next month.`;
数组
TypeScript像JavaScript一样可以操作数组元素。有两种方式可以定义数组。
- 第一种,可以在元素类型后面街上
[]
,表示由此类型元素组成的一个数组:
let list: number[] = [1, 2, 3];
- 第二种,使用数组泛型,
Array<元素类型>
let list: Array<number> = [1, 2, 3];
JavaScript中支持的所有数组操作,在TypeScript中都支持。
元组
元组类型允许表示一个已知元素数量和类型的数组,各元素的类型不必相同。比如,你可以定义一对值分别为string和number类型的元组。
// Declare a tuple type
let x: [string, number];
// Initialize it
x = ['hello', 10]; // OK
// Initialize it incorrectly
x = [10, 'hello']; // Error
枚举
enum
类型是对JavaScript标准数据类型的一个补充。像C#、Java等其他语言一样,使用枚举类型可以为一组数值赋予友好的名字。
enum Color {Red, Green, Blud}
let c: Color = Color.Green;
默认情况下,从 0
开始为元素编号。你也可以手动的指定成员的数值。例如,我们将上面的例子改成从 1
开始编号:
enum Color {Red = 1, Green, Blue}
let c: Color = Color.Green;
或者,全部都采用手动赋值:
enum Color {Red = 1, Green = 2, Blue = 4}
let c: Color = Color.Green;
枚举类型提供的一个便利是你可以由枚举的值得到它的名字。 例如,我们知道数值为2,但是不确定它映射到Color里的哪个名字,我们可以查找相应的名字:
enum Color {Red = 1, Green, Blue}
let colorName: string = Color[2];
console.log(colorName); // 显示'Green'因为上面代码里它的值是2
Any
有时候,我们会想要为那些在编程阶段还不清楚类型的变量指定一个类型。 这些值可能来自于动态的内容,比如来自用户输入或第三方代码库。 这种情况下,我们不希望类型检查器对这些值进行检查而是直接让它们通过编译阶段的检查。 那么我们可以使用 any类型来标记这些变量:
let notSure: any = 4;
notSure = "maybe a string instead";
notSure = false; // okay, definitely a boolean
在对现有代码进行改写的时候,any类型是十分有用的,它允许你在编译时可选择地包含或移除类型检查。 你可能认为 Object有相似的作用,就像它在其它语言中那样。 但是 Object类型的变量只是允许你给它赋任意值 - 但是却不能够在它上面调用任意的方法,即便它真的有这些方法:
let notSure: any = 4;
notSure.ifItExists(); // okay, ifItExists might exist at runtime
notSure.toFixed(); // okay, toFixed exists (but the compiler doesn't check)
let prettySure: Object = 4;
prettySure.toFixed(); // Error: Property 'toFixed' doesn't exist on type 'Object'.
当你只知道一部分数据的类型时,any类型也是有用的。 比如,你有一个数组,它包含了不同的类型的数据:
let list: any[] = [1, true, "free"];
list[1] = 100;
变量声明
let和const是JavaScript里相对较新的变量声明方式。 像我们之前提到过的, let在很多方面与var是相似的,但是可以帮助大家避免在JavaScript里常见一些问题。 const是对let的一个增强,它能阻止对一个变量再次赋值。
因为TypeScript是JavaScript的超集,所以它本身就支持let和const。 下面我们会详细说明这些新的声明方式以及为什么推荐使用它们来代替 var。
如果你之前使用JavaScript时没有特别在意,那么这节内容会唤起你的回忆。 如果你已经对 var声明的怪异之处了如指掌,那么你可以轻松地略过这节。
接口
TypeScript的核心原则之一是对值所具有的结构进行类型检查。 它有时被称做“鸭式辨型法”或“结构性子类型化”。 在TypeScript里,接口的作用就是为这些类型命名和为你的代码或第三方代码定义契约。
在TypeScript中,接口的定义和Java中结构的定义是类似的:
interface Point {
x: number;
y: number;
}
可选属性
接口里的属性不全都是必需的。 有些是只在某些条件下存在,或者根本不存在。 可选属性在应用“option bags”模式时很常用,即给函数传入的参数对象中只有部分属性赋值了。
interface Point {
x: number;
y: number;
label?: string;
}
只读属性
一些对象属性只能在对象刚刚创建的时候修改其值。 你可以在属性名前用 readonly来指定只读属性:
interface Point {
readonly x: number;
readonly y: number;
}
你可以通过赋值一个对象字面量来构造一个Point。 赋值后, x和y再也不能被改变了。
let p1: Point = { x: 10, y: 20 };
p1.x = 5; // error!
函数类型
接口能够描述JavaScript中对象拥有的各种各样的外形。 除了描述带有属性的普通对象外,接口也可以描述函数类型。
为了使用接口表示函数类型,我们需要给接口定义一个调用签名。 它就像是一个只有参数列表和返回值类型的函数定义。参数列表里的每个参数都需要名字和类型。
interface SearchFunc {
(source: string, subString: string): boolean;
}
类
传统的JavaScript程序使用函数和基于原型的继承来创建可重用的组件,但对于熟悉使用面向对象方式的程序员来讲就有些棘手,因为他们用的是基于类的继承并且对象是由类构建出来的。 从ECMAScript 2015,也就是ECMAScript 6开始,JavaScript程序员将能够使用基于类的面向对象的方式。 使用TypeScript,我们允许开发者现在就使用这些特性,并且编译后的JavaScript可以在所有主流浏览器和平台上运行,而不需要等到下个JavaScript版本。
TypeScript中的类和Java中的类相似:
class Greeter {
greeting: string;
constructor(message: string) {
this.greeting = message;
}
greet() {
return "Hello, " + this.greeting;
}
}
let greeter = new Greeter("world");