基础
基础类型:number string boolean array object
- enum 枚举 不显式赋值的话 0 1 2 顺延
enmu Status {
NOT_START,
STARTED
}
const status = Status.NOT_START;
- type inerface
type UserInfo = {
name: string;
height: number;
}
interface UserInfo {
name: string;
height: string;
}
-
联合类型 (|)
-
交叉类型 &
-
typeof
// js
typeof 'a' // string
// ts
function toArray (x: number): Array<number> {
return [x];
}
type Func = typeof toArray // (x: number) => number[]
- keyof
// 可以获取一个对象中所有的key
interface Person {
name: string;
age: number;
}
type KPerson = keyof Person;
const str: KPerson = 'name';
const str: KPerson = 'age';
- in
用来遍历枚举类型
type keys = 'a' | 'b' | 'c';
type Obj = {
[key in keys]: any
}
- extends 继承
interface ILength {
length: number;
}
function login <T extends ILength>(arg: T): T {
console.log(arr.length);
return arg;
}
-
paritial
patitial 将某个类型的属性全部变为可选项目
interface Page { title: string; content: string; } type OptionalPage = patitial<page>; -
required 将某个类型里的属性全部变成必选项目
-
Readonly
interface Page {
title: string;
}
const ReadonlyPage = Readonly<Page>
-
Record Record<K extends keyof any, T> 将K 中所有属性的值转化为T类型
-
Exclude
Exclude<T, U> 将某个类型中属于另一个的类型移除掉
type TO = Exclude<'a' | 'b' | 'c', 'a'> // 'b' | 'c' -
Extract
Extract<T, U> 取 T 和 U 的交集
进阶
-
ts的优势
- TS 是 JS 的超集,给js提供了可选的静态类型和基于面向对象,拓展了JS的语法。
- 类型约束
- 面向对象的编程语言,包含类和接口的概念
- 在开发时候就能给出编译错误
- 强类型语言,明确的知道各种数据的类型,代码可读性很强
- ts中有很多很方便的特性, 可选链
if (obj && obj.aa && obj.aa.bb) // if (obj?.aa?.bb) -
type 和 interface
用interface来描述数据结构,用type来描述类型
- 都支持描述一个对象或者函数
interface User { name: string; age: number; } type User = { name: string; age: number; }-
interface 与 type 都可以extends 可以互相extens
-
type 可以声明基本类型别名,联合类型,元组等类型
type Name = string; interface A {} interface B {} type pet = A | B; type pet = A & B; -
如果基于一个已有类型,扩展出一个大部分内容相似,但是部分区别的类型
Pick Omit
interface Test {
name: string;
sex: number;
height: string;
}
type Sex = Pick<Test, 'sex'>
const a:Sex = { sex: 1 };
type WithoutSex = Omit<Test, 'sex'>
const b: WithoutSex = { name: '1111', height: '100px' }
通用泛型
- 什么是泛型,泛型的具体使用
泛型是指在定义函数或者类的时候,不预先执行具体的类型,而是使用的时候再去指定类型的一种特征
interface Test<T = any> {
userId: T
}
type TestA = Test<string>
// { userId: string }
-
用装饰器实现一个计算函数运行时间的逻辑
export function measure (target, name, descriptor) {
const oldValue = descriptor.value; // 原有的函数
descriptor.value = async function () {
const startTime = Date.now();
const res = await oldValue.apply(this, arguments);
console.log(Date.now() - startTime)
}
return descriptor;
}
// 使用
@measure
created () {
console.log('呜呜呜');
}
- 缓存的装饰器
const cecheMap = new Map();
export function EnableCache (target, name, descriptor) {
const val = descriptor.value;
descriptor.value = async function (...args) {
const key = name + JSON.stringify(args);
if (!cacheMap.get(key)) {
const cacheValue = Promise.resolve(val.apply(this, args)).catch(_ => {
cacheMap.set(key, null)
});
cacheMap.set(key, cacheValue);
}
return cacheMap.get(key)
}
return descriptor;
}
- 实现路由跳转,通过ts约束参数的routerHelper
export type BaseRouterType = Dictionary<string> // { string: string }
export interface IndexParams extends BaseRouteType {
name: string
}
export interface ParamMap {
[Router.Index]: IndexParams
}
export class RouterHelper {
public replace<T extends RouterPath>(routePath: T, params: ParmMap[T]) {
Router.replace({
path: routePath,
query: params
})
}
public push<T extends RouterPath>(routePath: T, params: ParmMap[T]) {
Router.replace({
path: routePath,
query: params
})
}
}
- 实现一个基于ts和事件模式的countdown 基础类
import { EventEmitter } from 'eventemitter3';
export interface RemainTimeData {
/** 天数 */
days: number;
/**
* 小时数
*/
hours: number;
/**
* 分钟数
*/
minutes: number;
/**
* 秒数
*/
seconds: number;
/**
* 毫秒数
*/
count: number;
}
export type CountdownCallback = (remainTimeData: RemainTimeData, remainTime: number) => void;
// 倒计时状态
enum CountdownStatus {
running,
paused,
stoped,
}
/**
* 倒计时事件
*/
export enum CountdownEventName {
START = 'start',
STOP = 'stop',
RUNNING = 'running',
}
interface CountdownEventMap {
[CountdownEventName.START]: [];
[CountdownEventName.STOP]: [];
[CountdownEventName.RUNNING]: [RemainTimeData, number];
}
export function fillZero(num: number) {
return `0${num}`.slice(-2);
}
export class Countdown extends EventEmitter<CountdownEventMap> {
private static COUNT_IN_MILLISECOND: number = 1 * 100;
private static SECOND_IN_MILLISECOND: number = 10 * Countdown.COUNT_IN_MILLISECOND;
private static MINUTE_IN_MILLISECOND: number = 60 * Countdown.SECOND_IN_MILLISECOND;
private static HOUR_IN_MILLISECOND: number = 60 * Countdown.MINUTE_IN_MILLISECOND;
private static DAY_IN_MILLISECOND: number = 24 * Countdown.HOUR_IN_MILLISECOND;
private endTime: number;
private remainTime: number = 0;
private status: CountdownStatus = CountdownStatus.stoped;
private step: number;
constructor(endTime: number, step: number = 1e3) {
super();
this.endTime = endTime;
this.step = step;
// 初始化countdown实例的时候, 直接开始倒计时
this.start();
}
/** 开始倒计时 */
public start() {
// 发布事件:开始倒计时
this.emit(CountdownEventName.START);
// 更新状态为 倒计时进行中
this.status = CountdownStatus.running;
this.countdown();
}
/** 结束倒计时 */
public stop() {
// 发布事件:结束倒计时
this.emit(CountdownEventName.STOP);
// 更新状态为 倒计时结束
this.status = CountdownStatus.stoped;
}
private countdown() {
if (this.status !== CountdownStatus.running) {
return;
}
// 保证获取到的remainTime >= 0
this.remainTime = Math.max(this.endTime - Date.now(), 0);
// 发布事件 倒计时进行中, 并且传递时间数据
this.emit(CountdownEventName.RUNNING, this.parseRemainTime(this.remainTime), this.remainTime);
if (this.remainTime > 0) {
// 递归countdown
setTimeout(() => this.countdown(), this.step);
} else {
this.stop();
}
}
private parseRemainTime(remainTime: number): RemainTimeData {
let time = remainTime;
const days = Math.floor(time / Countdown.DAY_IN_MILLISECOND);
time = time % Countdown.DAY_IN_MILLISECOND;
const hours = Math.floor(time / Countdown.HOUR_IN_MILLISECOND);
time = time % Countdown.HOUR_IN_MILLISECOND;
const minutes = Math.floor(time / Countdown.MINUTE_IN_MILLISECOND);
time = time % Countdown.MINUTE_IN_MILLISECOND;
const seconds = Math.floor(time / Countdown.SECOND_IN_MILLISECOND);
time = time % Countdown.SECOND_IN_MILLISECOND;
const count = Math.floor(time / Countdown.COUNT_IN_MILLISECOND);
return {
days,
hours,
minutes,
seconds,
count,
};
}
}