基础篇

PlumliilAbout 5 min

基础篇

原始数据类性和 any

undefined 和 null 是所有类型的子类型

number 类型

不区分浮点和整数 支持二进制,八进制,十六进制

let num1: number = 100; // 十进制 100
let num2: number = 0b100; // 二进制 4
let num3: number = 0o100; // 八进制 64
let num4: number = 0x100; // 十六进制 256

boolean 类型

let flag: boolean = truelet flag: boolean = 20 > 30;

string 类型

默认情况下可以推导出类型可以不加 支持模板字符串 let msg:string='hello world'msg=num1:num1flag:{num1}--flag:{flag}--msg${msg}``

数组和元组

Array

let arrOfNumber: number[] = [1, 2, 3];
let arrOfString: string[] = ["a", "b", "c"];
let arrOfBoolean: boolean[] = [true, false];

Tuple

let user: [string, number] = ["zs", 19];
user.push("男");

interface 接口

对对象的形状(shape)进行描述 对函数类型进行描述 Duck Typing 鸭子类型

interface IPerson {
  readonly id: number;
  name: string;
  age: number;
  sex?: "男";
}

let user: IPerson = {
  id: 1,
  name: "zs",
  age: 19,
};

Function 函数

  • 在 js 中 函数是一等公民
function add(x: number, y: number, z?: number): number {
  if (typeof z === "number") return x + y + z;
  return x + y;
}
console.log(add(1, 2, 3));
interface ISum {
  (x: number, y: number, z?: number): number;
}
let add2: ISum = add;

类型推论,联合类型和类型断言

联合类型

let numOrStr: number | string;

只能访问共有方法(交集)

类型断言

使用as进行类型断言,使用者清楚知道某个值的详细信息

function getLength(value: string | number): number {
  const str = value as string;
  if (str.length) return str.length;
  const number = value as number;
  return number.toString().length;
}

类 Class

类(Class):定义了一起事物的抽象特点 对象(Object):类的实例 面向对象(OOP)三大特征:封装,继承,多态(不同实例不同方法)

  • private:私有,自己访问
  • public:公开访问
  • protected:自己以及子类访问
class Animal {
  readonly name: string;
  constructor(name: string) {
    this.name = name;
  }
  protected run() {
    return `${this.name} is running`;
  }
}

class Dog extends Animal {
  static color: string[] = ["yellow"];
  constructor(name: string) {
    super(name);
    console.log(this.name);
  }
  run() {
    return "Woo " + super.run();
  }
}
let tiger = new Animal("泰格");
// console.log(tiger.run()); // 属性“run”受保护,只能在类“Animal”及其子类中访问。
// tiger.name='tiger'; // 无法分配到 "name" ,因为它是只读属性。
let dh = new Dog("dahuang");
console.log(dh.run()); // Woo dahuang is running

类和接口

在 js 中,一个 class 只能继承自另一个 class,若其他类中的方法与属性也想继承,则很麻烦。而在 ts 中可以使用 implements 来实现一些类共有方法属性的提取。

interface Radio {
  switchRadio(trigger: boolean): void;
}
interface Battery {
  checkBatteryStatus(): void;
}
interface RadioWidthBattery extends Radio {
  checkBatteryStatus(): void;
}
// interface 抽象验证类的属性
// implements 实现方法

class Car implements Radio {
  switchRadio(trigger: boolean) {}
}
class Cellphone implements RadioWidthBattery {
  switchRadio(trigger: boolean) {}
  checkBatteryStatus() {}
}

上述两个类都有一个共同的方法,我们可以使用 interface 接口把他提取出来,implements 实现它。此时 car 和 cellphone 两个类中都需要有 switchRadio 方法,不然会报错。

interface 还可以继承,直接用 extends 即可

枚举

  • 常量值:const number
  • 计算值:computed number
enum Direction {
  Up,
  Down,
  Right,
  Left,
}

console.log(Direction.Up);
console.log(Direction.Left);
console.log(Direction[0]);
enum Direction {
  Up = "UP",
  Down = "DOWN",
  Right = "RIGHT",
  Left = "LEFT",
}

const value = "UP";
if (value === Direction.Up) {
  console.log("go up!");
}

类型别名,字面量和交叉类型

类型别名

type PlusType = (x: number, y: number) => number;
let sum: PlusType = (x, y) => {
  return x + y;
};
const result = sum(1, 2);
const result2 = sum(2, 3);
console.log(result, result2); // 3 5

type StrOrNumber = string | number;
let result3: StrOrNumber = "123";
result3 = 123;

字符串字面量

const str: "name" = "name";
const number: 1 = 1;

type Directions = "Up" | "Down" | "Left" | "Right";
let toWhere: Directions = "Left";

交叉类型

interface IName {
  name: string;
}

type IPerson = IName & { age: number };
let person: IPerson = { name: "zs", age: 19 };

声明文件

TypeScript 作为 JavaScript 的超集,在开发过程中不可避免要引用其他第三方的 JavaScript 的库。虽然通过直接引用可以调用库的类和方法,但是却无法使用 TypeScript 诸如类型检查等特性功能。为了解决这个问题,需要将这些库里的函数和方法体去掉后只保留导出类型声明,而产生了一个描述 JavaScript 库和模块信息的声明文件。通过引用这个声明文件,就可以借用 TypeScript 的各种特性来使用库文件了。

内置类型

类似 Date,RegExp...

const a: Array<number> = [1, 2, 3];
const date = new Date();

console.log(date.getTime());
const reg = /abc/;
console.log(reg.test("abc"));

console.log(Math.pow(2, 2));

let body = document.body;
let allLis = body.querySelectorAll("li");
allLis.length;
body.addEventListener("click", (e) => {
  console.log(e);
  e.preventDefault();
});
  • Omit 去除类型中某些项
    • type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;
    • Omit 会构造一个除类型 K 外具有 T 性质的类型
  • Pick 选取类型中指定类型
    • type Pick<T, K extends keyof T> = { [P in K] : T[P]; };
    • 从 T 中选择一组属性,将它们在 K 中联合
  • Partial 将类型中所有选项变为可选,即加上?
    • type Partial<T> = {[P in keyof T]?: T[P];};
  • Required 将类型中所有选项变为必选,去除所有?
    • type Required<T> = {[P in keyof T]-?: T[P];};

装饰器

类装饰器 ClassDecorator

const doc: ClassDecorator = (target: any) => {
  console.log(target);
  target.prototype.name = 'lee'
}

@doc
class Plumlee {
  constructor() {
  }
}


const plum: any = new Plumlee()
console.log('plum', plum.name);

修饰类 @doc等同于 doc(Plumlee) 我们可以通过装饰器来对类进行操作,修改属性等

属性装饰器 PropertyDecorator

const doc: PropertyDecorator = (target: any, key: string | symbol) => {
  console.log(target, key); // {} name
}

class Plumlee {
  @doc
  public name: string
  constructor() {
    this.name = 'lee'
  }
 
}


const plum: any = new Plumlee()

方法装饰器 MethodDecorator

const doc: MethodDecorator = (target: any, key: string | symbol, descriptor: any) => {
  console.log(target, key, descriptor);
//   {} getName {
//   value: [Function: getName],
//   writable: true,
//   enumerable: false,
//   configurable: true
// }
}

class Plumlee {
  public name: string
  constructor() {
    this.name = 'lee'
  }
  @doc
  getName() {}
}


const plum: any = new Plumlee()

实例:实现一个Get方法装饰器

import axios from 'axios'

const Get = (url: string) => {
  return (target: any, key: any, descriptor: PropertyDescriptor) => {
    const fnc = descriptor.value;
    axios.get(url).then(res => {
      fnc(res, {
        status: 200,
        success: true
      })
    }).catch(e => {
      fnc(e, {
        status: 500,
        success: false
      })
    })
  }
}

class Controller {
  constructor() { }
  @Get('https://api.apiopen.top/api/getHaoKanVideo?page=0&size=10')
  getList(res: any, status: any) {
    console.log({ res:res.data.result.list, status });
  }
}

参数装饰器

const doc: ParameterDecorator = (target: any, key: string | symbol | undefined, index: any) => {
  console.log(target, key, index); // {} getName 1
}

class Plumlee {
  public name: string
  constructor() {
    this.name = 'lee'
  }

  getName(name: string, @doc age: number) { }
}


const plum: any = new Plumlee()