ts入门


最近遇到了设计react组件的需求,再看antd源码时,发现用的ts,正好看下
https://www.runoob.com/typescript/ts-tutorial.html

1. ts简介

  • TypeScript 是 JavaScript 的一个超集,支持 ECMAScript 6 标准
  • TypeScript 是一种给 JavaScript 添加特性的语言扩展
  • Typescript是一种面向对象的Javascript语言

2. ts语法

TypeScript 程序由以下几个部分组成:

  • 模块
  • 函数
  • 变量
  • 语句和表达式
  • 注释

ts文件后缀为.ts

class Student {
    fullName: string;
    constructor(public firstName, public middleInitial, public lastName) {
        this.fullName = firstName + " " + middleInitial + " " + lastName;
    }
}

interface Person {
    firstName: string;
    lastName: string;
}

function greeter(person : Person) {
    return "Hello, " + person.firstName + " " + person.lastName;
}

let user = new Student("Jane", "M.", "User");

document.body.innerHTML = greeter(user);

以上文件需要使用tsc编译成js

// 运行 tsc greeter.ts后生成greeter.js
var Student = /** @class */ (function () {
    function Student(firstName, middleInitial, lastName) {
        this.firstName = firstName;
        this.middleInitial = middleInitial;
        this.lastName = lastName;
        this.fullName = firstName + " " + middleInitial + " " + lastName;
    }
    return Student;
}());
function greeter(person) {
    return "Hello, " + person.firstName + " " + person.lastName;
}
var user = new Student("Jane", "M.", "User");
document.body.innerHTML = greeter(user);

3. TypeScript 接口

接口是一系列抽象方法的声明,是一些方法特征的集合。
如果你只学过JS,那么你可以得到这样的通俗理解:接口类似于一个js对象原型,是一个方法模板。

// 以下实例中,我们定义了一个接口 IPerson,接着定义了一个变量 customer,它的类型是 IPerson。
interface IPerson { 
    firstName:string, 
    lastName:string, 
    sayHi: ()=>string 
} 
 
var customer:IPerson = { 
    firstName:"Tom",
    lastName:"Hanks", 
    sayHi: ():string =>{return "Hi there"} 
} 
 
console.log("Customer 对象 ") 
console.log(customer.firstName) 
console.log(customer.lastName) 
console.log(customer.sayHi())  

// interface是一个数组接口:数组的索引值和元素设置为不同类型,索引值是数字(当然你也可以设成字符串)
interface namelist { 
   [index:number]:string 
} 
 
// 类型一致,正确
var list2:namelist = ["Google","Runoob","Taobao"]
// 错误元素 1 不是 string 类型
// var list2:namelist = ["Runoob",1,"Taobao"]

注意接口不能转换为 JavaScript。 它只是 TypeScript 的一部分。

接口继承

interface Person { 
   age:number
}
// 单接口继承
interface Musician extends Person { 
   instrument:string
}
var drummer = {};
drummer.age = 27
drummer.instrument = "Drums"
console.log("年龄:  "+drummer.age)
console.log("喜欢的乐器:  "+drummer.instrument)

// 编译后js
var drummer = {};
drummer.age = 27;
drummer.instrument = "Drums";
console.log("年龄:  " + drummer.age);
console.log("喜欢的乐器:  " + drummer.instrument);

// 多接口继承
interface Child extends IParent1, IParent2 { }

4. TypeScript 类

类描述了所创建的对象共同的属性和方法。

// 创建来一个 Car 类,然后通过关键字 new 来创建一个对象并访问属性和方法
class Car {
   // 字段
   engine:string;

   // 构造函数
   constructor(engine:string) {
      this.engine = engine
   }

   // 方法:void 是一个正确的类型,告诉开发人员这个函数返回 undefined
   disp():void {
      console.log("函数中显示发动机型号  :   "+this.engine)
   }
}

// 创建一个对象
var obj = new Car("XXSY1")

// 访问字段
console.log("读取发动机型号 :  "+obj.engine)  

// 访问方法
obj.disp()

以下是编译后的结果

var Car = /** @class */ (function () {
    // 构造函数
    function Car(engine) {
        this.engine = engine;
    }
    // 方法
    Car.prototype.disp = function () {
        console.log("函数中显示发动机型号  :   " + this.engine);
    };
    return Car;
}());
// 创建一个对象
var obj = new Car("XXSY1");
// 访问字段
console.log("读取发动机型号 :  " + obj.engine);
// 访问方法
obj.disp();

输出:

读取发动机型号 :  XXSY1
函数中显示发动机型号  :   XXSY1

类的继承

class Circle extends Shape { }

注意:子类只能继承一个父类,TypeScript 不支持继承多个类,但支持多重继承

class Root {
   str:string;
}
class Child extends Root {} 
class Leaf extends Child {} // 多重继承,继承了 Child 和 Root 类

继承类后的方法重写

super 关键字是对父类的直接引用,该关键字可以引用父类的属性和方法

class PrinterClass {
   doPrint():void {
      console.log("父类的 doPrint() 方法。")
   }
}

class StringPrinter extends PrinterClass {
   doPrint():void {
      super.doPrint() // 调用父类的函数
      console.log("子类的 doPrint()方法。")
   }
}

static 关键字

static 关键字用于定义类的数据成员(属性和方法)为静态的,静态成员可以直接通过类名调用。

class StaticMem {
   static num:number;

   static disp():void { 
      console.log("num 值为 "+ StaticMem.num) 
   }
}

StaticMem.num = 12     // 初始化静态变量
StaticMem.disp()       // 调用静态方法

instanceof 运算符

JS用于判断对象类型,这里同理

lass Person{ } 
var obj = new Person() 
var isPerson = obj instanceof Person; 
console.log("obj 对象是 Person 类实例化来的吗? " + isPerson);

访问控制修饰符

  • public(默认) : 公有,可以在任何地方被访问。

  • protected : 受保护,可以被其自身以及其子类访问。

  • private : 私有,只能被其定义所在的类访问。

class Encapsulate {
   str1:string = "hello"
   private str2:string = "world"
}

var obj = new Encapsulate()
console.log(obj.str1)     // 可访问
console.log(obj.str2)   // 编译错误, str2 是私有的

类实现接口

实现(implements)是面向对象中的一个重要概念。一般来讲,一个类只能继承自另一个类,有时候不同类之间可以有一些共有的特性,这时候就可以把特性提取成接口(interfaces),用 implements 关键字来实现。这个特性大大提高了面向对象的灵活性。
举例来说,门是一个类,防盗门是门的子类。如果防盗门有一个报警器的功能,我们可以简单的给防盗门添加一个报警方法。这时候如果有另一个类,车,也有报警器的功能,就可以考虑把报警器提取出来,作为一个接口,防盗门和车都去实现它:

interface Alarm {
    alert(): void;
}

class Door {
}

class SecurityDoor extends Door implements Alarm {
    alert() {
        console.log('SecurityDoor alert');
    }
}
// 多个接口使用,分隔即可
class Car implements Alarm {
    alert() {
        console.log('Car alert');
    }
}

5. TypeScript对象

TypeScript 类型模板

var sites = {
    site1: "Runoob",
    site2: "Google",
    sayHello: function () { } // 类型模板,不同于js里面不需要这个
};
sites.sayHello = function () {
    console.log("hello " + sites.site1);
};
sites.sayHello();

鸭子类型(Duck Typing)

鸭子类型(英语:duck typing)是动态类型的一种风格,是多态(polymorphism)的一种形式。

在这种风格中,一个对象有效的语义,不是由继承自特定的类或实现特定的接口,而是由"当前方法和属性的集合"决定。

可以这样表述:

"当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。"

(别问我,我还没理解)

6. TypeScript 命名空间

namespace SomeNameSpaceName { 
   export interface ISomeInterfaceName {      }  
   export class SomeClassName {      }

//要在另外一个命名空间调用语法格式为:
SomeNameSpaceName.SomeClassName;

// 如果一个命名空间在一个单独的 TypeScript 文件中,则应使用三斜杠 /// 引用它,语法格式如下:
/// 

// 案例
// IShape.ts
namespace Drawing {
    export interface IShape {
        draw();
    }
}
}
// Circle.ts
/// 
namespace Drawing {
    export class Circle implements IShape {
        public draw() {
            console.log("Circle is drawn");
        }
    }
}

7.TypeScript 模块

模块是在其自身的作用域里执行,并不是在全局作用域,这意味着定义在模块里面的变量、函数和类等在模块外部是不可见的,除非明确地使用 export 导出它们。类似地,我们必须通过 import 导入其他模块导出的变量、函数、类等。

两个模块之间的关系是通过在文件级别上使用 import 和 export 建立的。

模块使用模块加载器去导入其它的模块:例如 Webpack。

语法

import someInterfaceRef = require("./SomeInterface");
// 案例

// IShape.ts
export interface IShape {
   draw();
}
// Circle.ts
import shape = require("./IShape");
export class Circle implements shape.IShape {
   public draw() { 
      console.log("Cirlce is drawn (external module)");
   }
}
// Triangle.ts
import shape = require("./IShape");
export class Triangle implements shape.IShape {
   public draw() {
      console.log("Triangle is drawn (external module)");
   }
}
// TestShape.ts
import shape = require("./IShape"); 
import circle = require("./Circle"); 
import triangle = require("./Triangle");  
 
function drawAllShapes(shapeToDraw: shape.IShape) {
   shapeToDraw.draw(); 
} 
 
drawAllShapes(new circle.Circle()); 
drawAllShapes(new triangle.Triangle());

// 使用 tsc 命令编译以上代码(Commonjs):
tsc --module commonjs TestShape.ts

8.TypeScript 声明文件

https://www.runoob.com/typescript/ts-ambient.html