TypeScript学习

基础数据类型

  1. 布尔,数字,字符串: boolean number string

多行 string 使用 `` 号

`` 号有运算作用 ${} 内部会当做变量或者表达式进行运算

  1. 数组:

    number[] 或 Array
    string[] 或 Array

  2. 元组:

    let x: [string, number];

    x = [“age”, 12]; 正确
    x = [12, “age”]; 错误

  3. Enum:

    enum Color {Red = 0, Green = 2, Blue = 4};
    let c: Color = Color.Red; => 0
    let name: string = Color[2]; => “Green”;

  4. Any 任意数据类型

    let a: any = 4;
    a = “im string”;
    a = false;

    let l: any[] = [1, false, “ok”];

  5. Void, void 类型的变量值仅能为 undefined or null

    let u: void = undefined / null;
    function do(): void {}

  6. 类型转换

    v 或 v as string

变量定义

使用 let 块作用域, const 常量 替代 var

解构:

  1. 数组解构:

    let username = [‘ono’, “xxx”, “yyy”];
    let [firstname, , lastname] = username;

1.1 变量交换:

[a, b] = [b, a];

1.2 函数参数:

function f([firstname, lastname]: [string, string]): string {
  return firstname + " " + lastname;
}

1.3 let [first, …rest] = [1,2,3,4,5]; => rest == [2,3,4,5]

  1. 对象解构:

    let user = {“username”: “xxx”, firstname: “yyy”, “lastname”: “zzz”, “age”: 22, “sex”:1}
    let {username, age} = user;

2.1 属性重命名:

let {username: UserName, age: Age} = user;
let {username: UserName, age: Age} : {username: string, age: number} = user;

3 函数声明

接口

  1. 对象接口:

    interface Person {
    name: string; // 必选参数
    age?: number; // 可选参数
    readonly sex: string; // 只读属性
    [propName: string]: any; // 允许 Person 包含其他属性, 而非仅 name, age, sex
    }

  2. ReadonlyArray 只读数组

只读数组内元素不可变, 不能将只读数组赋值给普通数组,
除非 let a: number[] = “ReadonlyArray“ as number[];

readonly 修饰属性, const 修饰变量

  1. 函数鸭子模型参数

    function f(p: Person){}

和含有缺省值对象 Person 做变量, 一起使用会造成歧义. 此时使用类型指定:

f(user) 错
f(user as Person) 正确
  1. 函数接口:

    interface Func {
    (username: string, password: string): boolean;
    }

    let verify: Func;
    verify = function(u, p) { return true/false; }
    ==> let verify = function(u: string, p: string): boolean {…}

  2. 数组接口: 只读不能赋值

    interface Arr {

}

  1. 类接口

    interface PersonInterface {
    username: string;
    setUsername(u: string);
    }

    class Student implements PersonInterface {
    username: string;
    setUsername(u: string) {this.username = u;}
    constructor(user: Person){}
    }

  2. 接口扩展与多继承

    interface A extends B {}
    interface A extends B, C {}

  3. 对象同时作为函数和对象, 并带有属性

  4. 接口继承类

class Student {
  static amount = 0;

  public office: number;
  private __username: string;
  constructor(u:string) {...}

  constructor(private __username: string) {} => 参数属性定义方法, 替代上面两行

  get username(): string { return this.__username; }
  set username(u:string) { this.__username = u; }

  sayHi() {return "Hi, "+this.username;}
}
  1. 继承类:

    class A extends B {
    constructor(u:string) {super(u);}
    }

  2. 默认为公有成员和方法

private 只能在本类中访问,
protected 只能在本类和派生类中访问,
public 可以在本类, 派生类和 ${实例}.属性/方法() 的方式访问

  1. 存取器

class Employee {
private username: string;
get username(): string { return this.
username; }
set username(u:string) { this.__username = u; }
}

  1. 静态属性 static

存在于类本身, 而非对象中, 该类全部对象公有.

  1. 抽象类 abstract

抽象类可以包含方法的实现; 接口只能定义方法名和参数返回值, 不能有实现.

函数

函数与匿名函数:

function add(x, y) { return x + y; }
let add = function (x, y) { return x + y; }

加入类型限制:

function add(x: number, y: number): number { return x + y; }
let add: (baseValue: number, incr: number)=>number = function (x: number, y: number): number { return x + y; };

可选参数与默认值:

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

剩余参数

function add(x: number, ...left: number[]) {...}

this, 使用() => {}替代 function(){} 和 假参数 (this: 类名)

更多 this 的文档

函数重载

function a(x: string): string;
function a(x: number): number;
function a(x): any {
  if (typeof x == "string") return "this is a string";
  else if (typeof x == "number") return 3.14;
}

泛型

泛型函数

function log<T> (arg: T): T {
  return arg;
}
let logger: <T>(arg: T)=>T = log;
let logger: {<T>(arg: T):T} = log;

改写后更明白 (arg: T):T 是 logger 的类型:

let logger: <T>(arg: T)=>T = log;
=> let logger: <T>(arg: T)=>T;
   logger = log;
let logger: {<T>(arg: T):T} = log;
=> let logger: {<T>(arg: T):T};
   logger = log;

使用 interface:

interface Logger {
  <T>(arg: T): T;
}
let logger: Logger = log;

interface Logger<T> {
  (arg: T): T;
}
let logger: Logger<number> = log;


log<string>("user");
log("user");

定义泛型:

let arr: Array<T>;

更多泛型文档

枚举

const enum Color {
  Red = 2,
  Green, // 3
  Blue = 5
}

let color = Color.Red; // 2
let index = Color[2];  // "Red"

类型推论, 类型兼容性 与 联合类型

string | number

类型保护:

http://www.tslang.cn/docs/handbook/type-inference.html
http://www.tslang.cn/docs/handbook/type-compatibility.html
http://www.tslang.cn/docs/handbook/advanced-types.html

Symbol

let sym = new Symbol();

作为对象属性来标记对象唯一性.

for .. in/of

for (let key in o) {}
for (let value in o) {}

模块

export const reg = /^[0-9]*$/
export function xx(){}
export interface yy{}
export class zz{}

以上写法类型 module.export.xx = xx;

export {xx}
export (xx as add}

类似 module.exports = {“add”: xx};

export _ from “./a”
export _ from “./b”
export * from “./c”

类似于将 lib 等模块, 整合到 index.js 里向外整体导出

export default function () {}

类似于 module.exports = function(){}

import {xx} from “./x”
import {xx as add} from “./x”
import * as MyModule from “./x”

命名空间

namespace XX { export function xx(){}; function yy(){}; }

使用 XX.xx()

同命名空间下, 分布在不同文件中的 export 方法可以相互直接调用, 没有 export 的不能调用

namespace XX ( export function zz(){ call xx(); but not yy()}; )

这里貌似测试不通过

模块, 命名空间, 模块解析

http://www.tslang.cn/docs/handbook/modules.html
http://www.tslang.cn/docs/handbook/namespaces.html
http://www.tslang.cn/docs/handbook/namespaces-and-modules.html

命名合并

接口: 多个声明合并到一起, 后声明的部分靠前

命名空间: 先声明的在前

模块扩展: http://www.tslang.cn/docs/handbook/declaration-merging.html

Donate - Support to make this site better.
捐助 - 支持我让我做得更好.