TypeScript 学习笔记

TypeScript 知识点的梳理。

基础类型

  • 布尔值: boolean

  • 数字: number

  • 字符串: string

  • 数组: any[]Array<any>

  • 元组: [string, number]

  • 枚举: enum Color {Red, Green, Blue} 从 0 开始,或 enum Color {Red = 1, Green, Blue} 从 1 开始

  • Any: any

  • Void: void

类型断言

把一个实体,强行设置为某个类型(告诉编译器这个实例就是这个类型,不用再检查,因为我已经手动检查过了)。
两种形式:

  • 尖括号语法
<string>someValue
  • as 语法
someValue as string

解构

作用于函数参数:

function f ([first, second]: [number, number]) {
    console.log(first);
    console.log(second);
}

作用于对象:

let {a, b}: {a: string, b: number} = obj;

接口

对象类型:

interface LabelledValue {
  label: string; // 必须包含一个label属性且类型为string
  size?: number; // 可选属性
  readonly x: number; // 只读属性 变量用const
  [propName: string]: any; // 其余未知属性
}

function printLabel(labelledObj: LabelledValue) {
  console.log(labelledObj.label);
}

let myObj = {size: 10, label: "Size 10 Object", x: 1};
printLabel(myObj);

函数类型:

// (参数类型) : 返回类型
interface SearchFunc {
  (a: string, b: string): boolean;
}

let mySearch: SearchFunc;
mySearch = function(source: string, subString: string) {
  let result = source.search(subString);
  return result > -1;
}

可索引的类型:

  • 数字索引
interface StringArray {
  [index: number]: string;
}

let myArray: StringArray;
myArray = ["Bob", "Fred"];

let myStr: string = myArray[0];
  • 字符串索引
    需要注意,数字索引返回值必须是字符串索引返回值的子类型,因为 js 查找索引会把数字转为字符串再查找。
interface NumberDictionary {
  [index: string]: number;
  length: number;    // 可以,length是number类型
  name: string       // 错误,`name`的类型与索引类型返回值的类型不匹配
}

类:
只描述了公共部分,不会帮你检查类是否具有某些私有成员。

interface ClockInterface {
    currentTime: Date;
    setTime(d: Date);
}

class Clock implements ClockInterface {
    currentTime: Date;
    setTime(d: Date) {
        this.currentTime = d;
    }
    constructor(h: number, m: number) { }
}

// 另一个例子
interface ClockConstructor {
    new (hour: number, minute: number): ClockInterface;
}
interface ClockInterface {
    tick();
}

function createClock(ctor: ClockConstructor, hour: number, minute: number): ClockInterface {
    return new ctor(hour, minute);
}

class DigitalClock implements ClockInterface {
    constructor(h: number, m: number) { }
    tick() {
        console.log("beep beep");
    }
}
class AnalogClock implements ClockInterface {
    constructor(h: number, m: number) { }
    tick() {
        console.log("tick tock");
    }
}

let digital = createClock(DigitalClock, 12, 17);
let analog = createClock(AnalogClock, 7, 32);

继承接口:

interface Shape {
    color: string;
}

interface Square extends Shape {
    sideLength: number;
}

let square = <Square>{};
square.color = "blue";
square.sideLength = 10;

public
默认为 public ,公共成员,可以自由访问。

private
私有,不能在当前类的外部访问。

protected :
只能在当前类或当前类的子类中访问。

存储器(getset):

// 设置密码
let passcode = "secret passcode";

class Employee {
    private _fullName: string;

    get fullName(): string {
        return this._fullName;
    }

    set fullName(newName: string) {
        // 只有密码正确时才有权限修改
        if (passcode && passcode == "secret passcode") {
            this._fullName = newName;
        }
        else {
            console.log("Error: Unauthorized update of employee!");
        }
    }
}

let employee = new Employee();
employee.fullName = "Bob Smith";
if (employee.fullName) {
    alert(employee.fullName);
}

静态属性 static
存在于类本身上面而不是类的实例上,调用时 类名.属性名,而不是 this.属性名(别的属性叫实例成员,那些仅当类被实例化的时候才会被初始化的属性)。

抽象类 abstract
类做为其它派生类的基类使用(多态)。 它们一般不会直接被实例化。

/**
 *  Animal 作为基类,makeSound 方法必须在派生类中实现
 *  当一个函数接受 Animal 类的实例作为参数时,肯定会有 move 和 makeSound 方法(多态)
 */
abstract class Animal {
    abstract makeSound(): void;
    move(): void {
        console.log('roaming the earch...');
    }
}

函数

let myAdd: (baseValue: number, increment: number) => number = // 定义类型
    function(x: number, y: number): number { return x + y; }; // 函数

// 或者在函数块省略类型,会自动识别
let myAdd: (baseValue: number, increment: number) => number =
    function(x, y) { return x + y; };

可选参数 :
TypeScript 中函数的参数数量,必须与定义类型时的参数数量一致,不能多不能少。

// 当参数是可选的时候,用 ?,且必须为最后参数
function buildName(firstName: string, lastName?: string):void {}

默认参数 :

function buildName(firstName: string, lastName = "Smith"):void {}

剩余参数 :
可以把所有参数收集到一个变量里。

function buildName(firstName: string, ...restOfName: string[]):void {}

重载 :
根据不同类型的参数,返回不同类型的值。

function pickCard(x: {suit: string; card: number; }[]): number;
function pickCard(x: number): {suit: string; card: number; };

function pickCard(x): any { // 这个类型检查并不是重载的一部分
    // Check to see if we're working with an object/array
    // if so, they gave us the deck and we'll pick the card
    if (typeof x == "object") {
        let pickedCard = Math.floor(Math.random() * x.length);
        return pickedCard;
    }
    // Otherwise just let them pick the card
    else if (typeof x == "number") {
        let pickedSuit = Math.floor(x / 13);
        return { suit: suits[pickedSuit], card: x % 13 };
    }
}

泛型

类型变量

// 表示返回值的类型与传入参数的类型是相同的
// T帮助我们捕获用户传入的类型(比如:number)
function identity<T>(arg: T): T {
    return arg;
}

// 使用方法一
let output = identity<string>("myString");
// 使用方法二 编译器会根据传入的参数自动地帮助我们确定T的类型
let output = identity("myString");

用接口表示

interface GenericIdentityFn<T> {
    (arg: T): T;
}

function identity<T>(arg: T): T {
    return arg;
}

let myIdentity: GenericIdentityFn<number> = identity;

// 或者
interface GenericIdentityFn {
    <T>(arg: T): T;
}

function identity<T>(arg: T): T {
    return arg;
}

let myIdentity: GenericIdentityFn = identity;

泛型类 :

class GenericNumber<T> {
    zeroValue: T;
    add: (x: T, y: T) => T;
}

let myGenericNumber = new GenericNumber<number>();
myGenericNumber.zeroValue = 0;
myGenericNumber.add = function(x, y) { return x + y; };

泛型约束 :

interface Lengthwise {
    length: number;
}

function loggingIdentity<T extends Lengthwise>(arg: T): T {
    console.log(arg.length); 
    return arg;
}

猜你喜欢

转载自blog.csdn.net/aq115aq/article/details/80565690