一、什么是TypeScript

TypeScript 是一种由微软开发的自由和开源的编程语言,它是 JavaScript 的一个超集,扩展了 JavaScript 的语法。

1,JavaScript VS TypeScript

a, TypeScript与JS的区别

TypeScript 是 JavaScript 的超集,扩展了 JavaScript 的语法,因此现有的 JavaScript 代码可与 TypeScript 一起工作无需任何修改,TypeScript 通过类型注解提供编译时的静态类型检查。
TypeScript 可处理已有的 JavaScript 代码,并只对其中的 TypeScript 代码进行编译。

b,TypeScript相比JS的优势

· 优势一:类型化思维方式,使开发更加严谨,提前发现错误,减少改bug时间
· 优势二:类型系统提高了代码可读性,并使维护和重构代码更加容易
· 优势三:补充了接口、枚举等开发大型应用时JS缺失的功能

2,特性:

  • 跨平台:TypeScript 编译器可以安装在任何操作系统上,包括 Windows、macOS 和 Linux
  • ES6特性:TypeScript 包含计划中的 ECMAScript 2015(ES6)的大部分特性,例如:箭头函数
  • 面向对象的语言:TypeScript 提供所有标准的 OOP 功能,如类、接口和模块
  • 静态类型检查:TypeScript 使用静态类型并帮助在编译时进行类检查。因此,你可以在编写代码时发现编译时错误,而无需运行脚本
  • 可选的静态类型:如果你习惯了 JavaScript 的动态类型,TypeScript 还允许可选的静态类型
  • DOM、BOM操作:可以使用 Typescript 来操作 DOM 以添加或者删除客户端网页元素
    1. let img = document.querySelector('#image') as HTMLImageElement
    2. // 对于 DOM 以及 BOM的操作,建议使用 javascript

二、TypeScript 安装

  1. // 需要安装提前安装npm
  2. npm install -g typescript
  3. //查看版本
  4. tsc -v
  5. // 如果需求编译时使用命令:tsc filename.ts

三、举个例子

1,创建项目文件夹tsDemo
2,新增一个html文件

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <title>Learning TypeScript</title>
  6. </head>
  7. <body>
  8. <script src="hello.js"></script>
  9. </body>
  10. </html>

3,新增一个ts文件

  1. alert('hello world in TypeScript!');

4,编译这个ts文件

  1. tsc hello.ts

5,双击tsDemo/index.html文件

四、基础知识

1,类型

ts的一大特色就是可以在不编译的情况下报错,就是因为她有类型批注这个功能,比如

  1. // 基础数据类型批注
  2. let isDone: boolean = false; // 布尔值
  3. let decLiteral: number = 6; // 数字
  4. let name: string = "bob"; // 字符串
  5. let list: number[] = [1, 2, 3]; // 数组1
  6. let list: Array<number> = [1, 2, 3]; // 数组2
  7. let x: [string, number] = ['hello', 10]; // 元组
  8. enum Color {Red, Green, Blue} // 枚举
  9. let c: Color = Color.Green;
  10. let notSure: any = 4; // 任意值
  11. notSure = "maybe a string instead";
  12. notSure = false;
  13. function warnUser(): void { // 空值 void一般表示函数无返回值
  14. alert("This is my warning message");
  15. }
  16. let u: undefined = undefined; // undefined类型
  17. let n: null = null; // null类型
  18. // Never类型
  19. function error(message: string): never { // 返回never的函数必须存在无法达到的终点
  20. throw new Error(message);
  21. }
  22. function fail() { // // 推断的返回值类型为never
  23. return error("Something failed");
  24. }
  25. function infiniteLoop(): never { // 返回never的函数必须存在无法达到的终点
  26. while (true) {
  27. }
  28. }

2,断言

当你遇到你比TypeScript更了解某个值的详细信息的时候。比如之前设置了any的值

  1. let someValue: any = "this is a string";
  2. let strLength: number = (<string>someValue).length; // 方法1
  3. let strLength: number = (someValue as string).length; //方法2 :推荐,因为当你在TypeScript里使用JSX时,只有as语法断言是被允许的。

3,函数声明

  1. type C = { a: string, b?: number }
  2. function f({ a, b }: C): void {
  3. // ...
  4. }

4,接口

  1. interface Point { // 混合类型
  2. x: number; // 普通属性
  3. readonly y: number; // 只读属性
  4. color?: string; // 可选属性
  5. reset(): void; //函数
  6. }
  7. // 函数类型
  8. interface SearchFunc {
  9. (source: string, subString: string): boolean;
  10. }
  11. let mySearch: SearchFunc;
  12. mySearch = function(source: string, subString: string) {
  13. let result = source.search(subString);
  14. return result > -1;
  15. }
  16. // 索引类型
  17. interface StringArray {
  18. [index: number]: string;
  19. }
  20. // 接口继承
  21. interface Shape {
  22. color: string;
  23. }
  24. interface Square extends Shape {
  25. sideLength: number;
  26. }
  27. // 类类型,implements关键字用来实现类类型接口
  28. interface ClockInterface {
  29. currentTime: Date;
  30. }
  31. class Clock implements ClockInterface {
  32. currentTime: Date;
  33. constructor(h: number, m: number) { }
  34. }

5,类

  1. class Greeter {
  2. greeting: string;
  3. constructor(message: string) {
  4. this.greeting = message;
  5. }
  6. greet() {
  7. return "Hello, " + this.greeting;
  8. }
  9. }
  10. let greeter = new Greeter("world");
  1. class Animal {
  2. name: string;
  3. constructor(theName: string) { this.name = theName; }
  4. move(distanceInMeters: number = 0) {
  5. console.log(`${this.name} 移动 ${distanceInMeters}米.`);
  6. }
  7. }
  8. class Snake extends Animal { // 作为派生类,通过extends关键字继承Animal类。
  9. constructor(name: string) { super(name); }
  10. move(distanceInMeters = 5) {
  11. console.log("滑行中...");
  12. super.move(distanceInMeters);
  13. }
  14. }
  15. // 派生类包含了一个构造函数,它必须调用super(),
  16. // 它会执行基类的构造函数。 而且,在构造函数里访问this的属性之前,我们一定要调用super()。
  17. // 这个是TypeScript强制执行的一条重要规则。
  18. class Horse extends Animal {
  19. constructor(name: string) { super(name); }
  20. move(distanceInMeters = 45) {
  21. console.log("奔跑中...");
  22. super.move(distanceInMeters);
  23. }
  24. }
  25. let sam = new Snake("蛇三");
  26. let tom: Animal = new Horse("马四");
  27. sam.move();
  28. tom.move(34);
  1. // alert('hello world in TypeScript!');
  2. class User {
  3. static age = 23; // 静态属性,存在于类本身上,访问时不需要实例化
  4. readonly id: number; // 可以访问,但是一旦确定不能修改
  5. protected username: string; // 自身和子类可以访问,但是不能外部修改
  6. private password: string; // 外部包括子类不能访问,也不可以修改
  7. public info: string; // 默认的,可以去掉public修饰符
  8. constructor(id: number, username: string, password: string, info: string) {
  9. this.id = id;
  10. this.username = username;
  11. this.password = password;
  12. this.info = info;
  13. }
  14. getInfo() {
  15. console.log(this.id, `this.id`);
  16. console.log(this.username, `this.username`);
  17. console.log(this.password, `this.password`);
  18. console.log(this.info, `this.info`);
  19. }
  20. //可以通过public方法修改private属性
  21. setPassword(password: string) {
  22. if (password.length >= 6) {
  23. this.password = password;
  24. }
  25. }
  26. }
  27. class Vip extends User {
  28. getInfo2() {
  29. console.log(this.id, `this.id`);
  30. console.log(this.username, `this.username`);
  31. // console.log(this.password,`this.password`); //报错,私有类
  32. console.log(this.info, `this.info`);
  33. }
  34. }
  35. console.log(`User.age`,User.age);
  36. let user1 = new User(1, '张三', '123456', '打工人');
  37. user1.getInfo();
  38. let vip = new Vip(1, '李四', '000000', '人上人');
  39. vip.getInfo2();
  40. console.log(user1.id, `user1.id;`);
  41. // console.log(user1.username,`user1.username;`); // 报错,保护类 只有自身和子类可以访问
  42. // console.log(user1.password,`user1.password;`); // 报错,私有类,只有自身可以访问
  43. console.log(user1.info, `user1.info;`);
  1. abstract class Department {
  2. constructor(public name: string) {
  3. }
  4. printName(): void {
  5. console.log('部门名称: ' + this.name);
  6. }
  7. abstract printMeeting(): void; // 必须在派生类中实现
  8. }
  9. class AccountingDepartment extends Department {
  10. constructor() {
  11. super('会计'); // 在派生类的构造函数中必须调用 super()
  12. }
  13. printMeeting(): void {
  14. console.log('会计部门在每周一上午10点开会.');
  15. }
  16. generateReports(): void {
  17. console.log('报告生成中...');
  18. }
  19. }
  20. let department: Department; // 允许创建一个对抽象类型的引用
  21. // department = new Department(); // 错误: 不能创建一个抽象类的实例
  22. department = new AccountingDepartment(); // 允许对一个抽象子类进行实例化和赋值
  23. department.printName();
  24. department.printMeeting();
  25. // department.generateReports(); // 错误: 方法在声明的抽象类中不存在
  1. class Point {
  2. x: number;
  3. y: number;
  4. }
  5. interface Point3d extends Point {
  6. z: number;
  7. }
  8. let point3d: Point3d = {x: 1, y: 2, z: 3};

6,函数

  1. function add(x: number, y: number): number {
  2. return x + y;
  3. }
  4. // 完整的函数类型定义
  5. let myAdd: (x:number, y:number) => number =
  6. function(x: number, y: number): number { return x + y; };
  7. // 类型推断
  8. let myAdd = function(x: number, y: number): number { return x + y; };
  9. // 可选参数
  10. function buildName(firstName: string, lastName?: string) {
  11. if (lastName)
  12. return firstName + " " + lastName;
  13. else
  14. return firstName;
  15. }
  16. let result1 = buildName("Bob"); // works correctly now
  17. let result2 = buildName("Bob", "Adams", "Sr."); // error, too many parameters
  18. let result3 = buildName("Bob", "Adams"); // ah, just right
  19. // 默认参数
  20. function buildName(firstName: string, lastName = "Smith") {
  21. return firstName + " " + lastName;
  22. }
  23. let result1 = buildName("Bob"); // works correctly now, returns "Bob Smith"
  24. let result2 = buildName("Bob", undefined); // still works, also returns "Bob Smith"
  25. let result3 = buildName("Bob", "Adams", "Sr."); // error, too many parameters
  26. let result4 = buildName("Bob", "Adams"); // ah, just right
  27. // 剩余参数
  28. function buildName(firstName: string, ...restOfName: string[]) {
  29. return firstName + " " + restOfName.join(" ");
  30. }
  31. let buildNameFun: (fname: string, ...rest: string[]) => string = buildName;
  32. // 重载:为同一个函数提供多个函数类型定义来进行函数重载,根据参数不同调用不同函数
  33. let suits = ["hearts", "spades", "clubs", "diamonds"];
  34. function pickCard(x: {suit: string; card: number; }[]): number;
  35. function pickCard(x: number): {suit: string; card: number; };
  36. function pickCard(x): any {
  37. // Check to see if we're working with an object/array
  38. // if so, they gave us the deck and we'll pick the card
  39. if (typeof x == "object") {
  40. let pickedCard = Math.floor(Math.random() * x.length);
  41. return pickedCard;
  42. }
  43. // Otherwise just let them pick the card
  44. else if (typeof x == "number") {
  45. let pickedSuit = Math.floor(x / 13);
  46. return { suit: suits[pickedSuit], card: x % 13 };
  47. }
  48. }
  49. let myDeck = [{ suit: "diamonds", card: 2 }, { suit: "spades", card: 10 }, { suit: "hearts", card: 4 }];
  50. let pickedCard1 = myDeck[pickCard(myDeck)];
  51. alert("card: " + pickedCard1.card + " of " + pickedCard1.suit);
  52. let pickedCard2 = pickCard(15);
  53. alert("card: " + pickedCard2.card + " of " + pickedCard2.suit);

7,泛型

  1. // 泛型函数
  2. function identity<T>(arg: T): T {
  3. return arg;
  4. }
  5. // 泛型接口
  6. interface GenericIdentityFn<T> {
  7. (arg: T): T;
  8. }
  9. // 泛型类
  10. class GenericNumber<T> {
  11. zeroValue: T;
  12. add: (x: T, y: T) => T;
  13. }
  14. let myGenericNumber = new GenericNumber<number>();
  15. myGenericNumber.zeroValue = 0;
  16. myGenericNumber.add = function(x, y) { return x + y; };
  17. // 泛型约束
  18. interface Lengthwise {
  19. length: number;
  20. }
  21. function loggingIdentity<T extends Lengthwise>(arg: T): T {
  22. console.log(arg.length); //扩展中表示参数是有length这个原型方法的
  23. return arg;
  24. }
  25. let logs = loggingIdentity(['abc'])

中文文档:https://typescript.bootcss.com/