官方文档
TypeScript 是给 JavaScript 添加特性的语言扩展,支持 ECMAScript 6 标准。通过类型注解提供编译时的静态类型检查,遵循强类型。
++ 增加功能
类型批注和编译时类型检查
类型推断
类型擦除
接口
枚举
Mixin
泛型编程
名字空间
元组
Await
++ ECMA 2015 反向移植
类
模块
lambda 函数的箭头语法
可选参数以及默认参数
TypeScript 安装
npm install -g typescript
# 查看版本号
tsc -v
# TypeScript 转换为 JavaScript 代码
tsc test.ts
基础类型
any、number、string、boolean、数组、元组、枚举、void、null、undefined、never
- 声明为 never 类型的变量只能被 never 类型所赋值,在函数中它通常表现为抛出异常或无法执行到终止点
- undefined 和 null 是所有类型的子类型
- 数组的项中不允许出现其他的类型,数组的一些方法的参数也会根据数组在定义时约定的类型进行限制
1 | let name: string = "Runoob"; |
any 使用场景
++ 变量的值会动态改变
1 | let x: any = 1; |
变量声明
var [变量名] : [类型] = 值; //类型,初始值可选
类型断言
<类型>值 \ 值 as 类型
类型断言纯粹是一个编译时语法,不被称为类型转换
类型推断
由于缺乏声明而不能推断出类型,那么它的类型被视作默认的动态 any 类型
函数
// 函数声明(Function Declaration)
function sum(x: number, y: number): number {
return x + y;
}
// 函数表达式(Function Expression)
let mySum: (x: number, y: number) => number = function (x: number, y: number): number {
return x + y;
}
=> 用来表示函数的定义,左边是输入类型,需要用括号括起来,右边是输出类型。
可选参数
在 TypeScript 函数里,如果我们定义了参数,则我们必须传入这些参数,除非将这些参数设置为可选,可选参数使用问号标识 ?。可选参数必须跟在必需参数后面。
TypeScript 会将添加了默认值的参数识别为可选参数,此时就不受「可选参数必须接在必需参数后面」的限制
function buildName(firstName: string, lastName?: string) {
return firstName + " " + lastName;
}
剩余参数
剩余参数语法允许我们将一个不确定数量的参数作为一个数组传入。rest 参数只能是最后一个参数
function buildName(firstName: string, ...restOfName: string[]) {
return firstName + " " + restOfName.join(" ");
}
函数重载
TypeScript 会优先从最前面的函数定义开始匹配,所以多个函数定义如果有包含关系,需要优先把精确的定义写在前面。
function disp(s1:string):void;
function disp(n1:number,s1:string):void;
function disp(x:any,y?:any):void {
console.log(x);
console.log(y);
}
联合类型
var val:string|number
var arr:number[]|string[];
接口
接口不能转换为 JavaScript。 它只是 TypeScript 的一部分。
interface IPerson {
firstName:string,
lastName:string,
sayHi: ()=>string
}
var customer:IPerson = {
firstName:"Tom",
lastName:"Hanks",
sayHi: ():string =>{return "Hi there"}
}
接口中我们可以将数组的索引值和元素设置为不同类型,索引值可以是数字或字符串。
interface namelist {
[index:number]:string
}
interface ages {
[index:string]:number
}
接口继承
# 单继承
interface Person {
age:number
}
interface Musician extends Person {
instrument:string
}
# 多继承
interface IParent1 {
v1:number
}
interface IParent2 {
v2:number
}
interface Child extends IParent1, IParent2 { }
类
class Car {
// 字段
engine:string;
// 构造函数
constructor(engine:string) {
this.engine = engine
}
// 方法
disp():void {
console.log("发动机为 : "+this.engine)
}
}
TypeScript 一次只能继承一个类,不支持继承多个类,但 TypeScript 支持多重继承(A 继承 B,B 继承 C)。
class Shape {
Area:number
constructor(a:number) {
this.Area = a
}
}
class Circle extends Shape {
disp():void {
console.log("圆的面积: "+this.Area)
}
}
继承类的方法重写
++ super 关键字是对父类的直接引用,该关键字可以引用父类的属性和方法。
class PrinterClass {
doPrint():void {
console.log("父类的 doPrint() 方法。")
}
}
class StringPrinter extends PrinterClass {
doPrint():void {
super.doPrint() // 调用父类的函数
console.log("子类的 doPrint()方法。")
}
}
static 关键字
static 关键字用于定义类的数据成员(属性和方法)为静态的,静态成员可以直接通过类名调用。
instanceof 运算符
判断对象是否是指定的类型的实例
访问控制修饰符
public(默认) : 公有,可以在任何地方被访问。
protected : 受保护,可以被其自身以及其子类和父类访问。
private : 私有,只能被其定义所在的类访问。
类和接口
类可以实现接口,使用关键字 implements,并将 interest 字段作为类的属性使用。
interface ILoan {
interest:number
}
class AgriLoan implements ILoan {
interest:number
rebate:number
constructor(interest:number,rebate:number) {
this.interest = interest
this.rebate = rebate
}
}
对象
Typescript 中的对象必须是特定类型的实例。
var sites = {
site1: "Runoob",
site2: "Google",
sayHello: function () { } // 类型模板
};
sites.sayHello = function () {
console.log("hello " + sites.site1);
};
命名空间
命名空间使用 namespace 来定义,如果我们需要在外部可以调用 命名空间 中的类和接口,则需要在类和接口添加 export 关键字。 命名空间可以嵌套。
namespace Drawing {
export interface IShape {
draw();
}
}
模块
模块导出使用关键字 export 关键字
另外一个文件使用该模块就需要使用 import 关键字来导入
export interface IShape {
draw();
}
import shape = require("./IShape");
export class Circle implements shape.IShape {
public draw() {
console.log("Cirlce is drawn (external module)");
}
}
声明文件
declare 定义的类型只会用于编译时的检查,编译结果中会被删除。
常用语法
declare var 声明全局变量
declare function 声明全局方法
declare class 声明全局类
declare enum 声明全局枚举类型
declare namespace 声明(含有子属性的)全局对象
interface 和 type 声明全局类型
export 导出变量
export namespace 导出(含有子属性的)对象
export default ES6 默认导出
export = commonjs 导出模块
export as namespace UMD 库声明全局变量
declare global 扩展全局变量
declare module 扩展模块
/// <reference /> 三斜线指令
declare var jQuery: (selector: string) => any;
声明文件以 .d.ts 为后缀
declare module Runoob {
export class Calc {
doSum(limit:number) : number;
}
}
引入声明文件
/// <reference path = "Calc.d.ts" />
var obj = new Runoob.Calc();
第三方声明文件
npm install @types/jquery --save-dev
++ 声明文件检索
内置对象
ECMAScript 的内置对象
Boolean、Error、Date、RegExp
DOM 和 BOM 的内置对象
Document、HTMLElement、Event、NodeList
let body: HTMLElement = document.body;
let allDiv: NodeList = document.querySelectorAll('div');
document.addEventListener('click', function(e: MouseEvent) {
// Do something
});
TypeScript 核心库的定义中不包含 Node.js 部分。
//用 TypeScript 写 Node.js
npm install @types/node --save-dev