TypeScript | 青训营笔记

36 阅读4分钟

这是我参与「第四届青训营 」笔记创作活动的第7天

TypeScript

介绍

TypeScript 由微软开发,是 JavaScript 的一个超集,支持 ECMAScript 6 标准。TypeScript的目标是开发大型应用,它可以编译成纯JavaScript。

JS和TS的区别: TypeScript 是 JavaScript 的超集,扩展了 JavaScript 的语法,因此现有的 JavaScript 代码可与 TypeScript 一起工作无需任何修改。

安装

使用NPM安装:

npm install -g typescript

安装成功后使用tsc命令执行相关操作:

tsc -v  # 查看版本号

HelloWorld

新建test.ts文件,编写代码:

const test:string = "hello world!";

console.log(test);

使用命令将ts代码编译成js代码:

tsc test,ts

执行后生成了test.js

执行js文件,通过node或浏览器。

语法

TS扩展了JS,原来JS的语法都一样使用:

let a = 10;

console.log(a);

所以学习ts需要学习的只是扩展的语法,主要就是加上数据类型的JS。

编译时类型检查

let [变量名]:[类型] = 值;

如果值不是声明的类型会报错。

let a:number = 10;
a = "hello";    // 报错,编译不通过

数据类型:

  • any类型:
let a:any = 10;
a = "hello";
  • string类型:
let str:string = "hello";
  • numbe类型:
let n:number = 10;
  • 布尔类型:
let b:boolean = true;
  • 数组类型:数据元素的类型相同(any类型可以不同)
// 在元素类型后面加上[]
let arr: number[] = [1, 2];

// 或者使用数组泛型
let arr: Array<number> = [1, 2];
  • 元组:存储的多个元素数据类型不同
let x: [string, number];
x = ['test', 1]; 
  • 枚举:定义常量集合
enum Color {Red, Green, Blue};
let c: Color = Color.Blue;
console.log(c);    // 输出 2
  • null和undifine:
let x: number;
x = 1; // 编译正确
x = undefined;    // 编译错误
x = null;    // 编译错误
  • 允许出现null或undifine:
let x: number | null | undefined;
x = 1; // 编译正确
x = undefined;    // 编译正确
x = null;    // 编译正确
  • 允许多个类型(联合类型):
let test:number|string = 10;
test = "abc";
  • never类型: never 是其它类型(包括 null 和 undefined)的子类型,代表从不会出现的值。声明为 never 类型的变量只能被 never 类型所赋值,在函数中它通常表现为抛出异常或无法执行到终止点(例如无限循环)。
let x: never;
let y: number;

// 编译错误,数字类型不能转为 never 类型
// x = 123;

// 正确,never 类型可以赋值给 never类型
x = (()=>{ throw new Error('exception')})();

// 正确,never 类型可以赋值给 数字类型
y = (()=>{ throw new Error('exception')})();

// 返回值为 never 的函数可以是抛出异常的情况
function error(message: string): never {
    throw new Error(message);
}

// 返回值为 never 的函数可以是无法被执行到的终止点的情况
function loop(): never {
    while (true) {}
}

函数的参数类型和返回值类型

指定参数x,y必须为number类型,返回值为number类型:

function add(x:number, y:number):number {
    return x + y;
}

// add("a", 2);    // 报错
console.log(add(2,3));  // 输出5

如果声明了参数,则调用的时候必须要传入指定类型和数量的参数:

function buildName(firstName: string, lastName: string) {
    return firstName + " " + lastName;
}
 
let result1 = buildName("Bob");                  // 错误,缺少参数
let result2 = buildName("Bob", "Adams", "Sr.");  // 错误,参数太多了
let result3 = buildName("Bob", "Adams");         // 正确

可以使用?设置可选参数:

function buildName(firstName: string, lastName?: string) {
    if (lastName)
        return firstName + " " + lastName;
    else
        return firstName;
}
 
let result1 = buildName("Bob");  // 正确
let result2 = buildName("Bob", "Adams", "Sr.");  // 错误,参数太多了
let result3 = buildName("Bob", "Adams");  // 正确

设置参数的默认值:

function buildName(firstName: string, lastName: string = "xs") {
    return firstName + lastName;
}

传入多个参数:

function buildName(firstName: string, ...restOfName: string[]) {
    return firstName + " " + restOfName.join(" ");
}
  
let employeeName = buildName("Joseph", "Samuel", "Lucas", "MacKinzie");

没有函数名的匿名函数:

const fun = function(x:number, y:number):number {
    return x + y;
}

// 自调用
let res = function(x:number, y:number):number {
    return x + y;
}(2,3);

箭头函数:

const foo = (x:number, y:number):number => {return x + y}

foo(2,3)

接口

接口是一系列抽象方法的声明,是一些方法特征的集合,这些方法都应该是抽象的,需要由具体的类去实现,然后第三方就可以通过这组抽象方法调用,让具体的类执行具体的方法。

// 定义接口
interface IPerson { 
    firstName:string, 
    lastName:string, 
    sayHi: ()=>string 
} 
 
// 实现接口 
let customer:IPerson = { 
    firstName:"Tom",
    lastName:"Hanks", 
    sayHi: ():string =>{return "Hi there"} 
}

let employee:IPerson = { 
    firstName:"Jim",
    lastName:"Blakes", 
    sayHi: ():string =>{return "Hello!!!"} 
}