Skip to content

Latest commit

 

History

History
242 lines (183 loc) · 4.19 KB

day_003.md

File metadata and controls

242 lines (183 loc) · 4.19 KB

day 3

TS基础

ts 基础中文文档

TS进阶

深入理解 TypeScript


摘抄:

使用数字类型作为标志

enum AnimalFlags {
    None = 0,
    HasClaws = 1 << 0,
    CanFly = 1 << 1,
    EatsFish = 1 << 2,
    Endangered = 1 << 3
}

interface Animal {
    flags: AnimalFlags;

    [key: string]: any;
}

function printAnimalAbilities(animal: Animal) {
    var animalFlags = animal.flags;
    if (animalFlags & AnimalFlags.HasClaws) {
        console.log('animal has claws');
    }
    if (animalFlags & AnimalFlags.CanFly) {
        console.log('animal can fly');
    }
    if (animalFlags == AnimalFlags.None) {
        console.log('nothing');
    }
}
//你可以组合标志,用来在枚举类型中定义方便快捷的方式
enum AnimalFlags {
  None        = 0,
  HasClaws    = 1 << 0,
  CanFly      = 1 << 1,
  EatsFish    = 1 << 2,
  Endangered  = 1 << 3,

  EndangeredFlyingClawedFishEating = HasClaws | CanFly | EatsFish | Endangered
}

有静态方法的枚举

可以使用 enum + namespace 的声明的方式向枚举类型添加静态方法

enum Weekday {
  Monday,
  Tuesday,
  Wednesday,
  Thursday,
  Friday,
  Saturday,
  Sunday
}

namespace Weekday {
  export function isBusinessDay(day: Weekday) {
    switch (day) {
      case Weekday.Saturday:
      case Weekday.Sunday:
        return false;
      default:
        return true;
    }
  }
}

const mon = Weekday.Monday;
const sun = Weekday.Sunday;

console.log(Weekday.isBusinessDay(mon)); // true
console.log(Weekday.isBusinessDay(sun));

单例模式

class Singleton {
  private static instance: Singleton;
  private constructor() {
    // ..
  }

  public static getInstance() {
    if (!Singleton.instance) {
      Singleton.instance = new Singleton();
    }

    return Singleton.instance;
  }

  someMethod() {}
}

let someThing = new Singleton(); // Error: constructor of 'singleton' is private

let instacne = Singleton.getInstance(); // do some thing with the instance

不想延迟初始化,可以使用 namespace 替代:

namespace Singleton {
  // .. 其他初始化的代码

  export function someMethod() {}
}

// 使用
Singleton.someMethod();

大部分使用者来说,namespace 可以用模块来替代

// someFile.ts
// ... any one time initialization goes here ...
export function someMethod() {}

// Usage
import { someMethod } from './someFile';

惰性字面量

快速解决方案

let foo = {} as any;
foo.bar = 123;
foo.bas = 'Hello World';

折中的解决方案

总是用 any 肯定是不好的,因为这样做其实是在想办法绕开 TypeScript 的类型检查。那么,折中的方案就是创建 interface,这样的好处在于:

  • 方便撰写类型文档

  • TypeScript 会参与类型检查,确保类型安全

interface Foo {
  bar: number;
  bas: string;
}

let foo = {} as Foo;
foo.bar = 123;
foo.bas = 'Hello World';

最好的解决方案

let foo = {
  bar: 123,
  bas: 'Hello World'
};

柯里化

/ 一个柯里化函数
let add = (x: number) => (y: number) => x + y;

// 简单使用
add(123)(456);

// 部分应用
let add123 = add(123);

// fully apply the function
add123(456);

type 和 interface的区别

简书文章地址

联合类型必须要type

//联合类型 和  交叉类型
type StringNumber = string | number;
let a: StringNumber;
a = "1";
a = 7;

Utility Types也必须要要用type

Utility Types 官网

interface可以合并同名接口,type不可以

interface A {
    name: string
}

interface A {
    age: number
}

var x: A = {name: 'xx', age: 20}

interface可以继承interface,继承type,使用extends关键字,type也可继承type,也可继承interface,使用&

interface A {
    name: string
}

interface B extends A {
    age: number
}

type C = { sex: string }

interface D extends C {
    name: string
}

type E = { name: string } & C

type F = { age: number } & A