This is the 23rd day of my participation in the November Gwen Challenge. Check out the event details: The last Gwen Challenge 2021

TIP 👉 A hero is a man who has great ambition, good policy in his belly, the opportunity to contain the universe and swallow the ambition of heaven and earth. — Romance of The Three Kingdoms

preface

In actual combat

  1. What do you think are the benefits of using TS?

1.1 TypeScript is an enhanced version of JavaScript that expands the syntax of JavaScript by adding optional static typing and class-based object-oriented programming. As a result, TS has only a few more features than JS. 1.2 Typescript is a pure object-oriented programming language, including the concepts of classes and interfaces. 1.3 TS provides compilation errors at development time, whereas JS errors are exposed at runtime. 1.4 As a strongly typed language, you can clearly know the type of data. The code is so readable that almost everyone can understand it. There are many handy features in 1.5TS, such as optional chains.

  1. Similarities and differences between Type and interface

Key: Use interface to describe data structures, and use type to describe types

2.1 Can describe an object or function

interface User {
  name: string
  age: number
}

interface SetUser {
  (name: string.age: number) :void;
}

type User = {
  name: string
  age: number
};

type SetUser = (name: string, age: number) = > void;
Copy the code

Both interface and Type extend and are not independent of each other. That is to say, interface can extend Type and Type can extend Interface. The effect is similar, but the syntax is different.

// interface extends interface
interface Name { 
  name: string; 
}
interface User extends Name { 
  age: number; 
}

// type extends type
type Name = { 
  name: string; 
}
type User = Name & { age: number  };

// interface extends type
type Name = { 
  name: string; 
}
interface User extends Name { 
  age: number; 
}

// type extends interface
interface Name { 
  name: string; 
}
type User = Name & { 
  age: number; 
}
Copy the code

2.3 Only Type can do this

Type can declare basic type aliases, union types, tuples, and so on

// Base type alias
type Name = string

// Union type
interface Dog {
    wong();
}
interface Cat {
    miao();
}

type Pet = Dog | Cat

// Specify the type of each position in the array
type PetList = [Dog, Pet]

When you want to get the typeof a variable, use typeof
let div = document.createElement('div');
type B = typeof div
Copy the code
  1. How do you extend an existing type that is mostly similar, but partially different?

Use Pick and Omit first

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: 'sss' };
Copy the code

Such as Partial, Required.

You can also use generics.

  1. What are generics and how are they used?

Generics are the feature of defining functions, interfaces, or classes without specifying a specific type in advance.

You can think of generics as parameters that represent types

interface Test<T = any> {
    userId: T;
}

type TestA = Test<string>;
type TestB = Test<number>;

const a: TestA = {
    userId: '111'};const b: TestB = {
    userId: 2222};Copy the code
  1. Implement a Countdown base class based on TS and event mode

import { EventEmitter } from 'eventemitter3';

export interface RemainTimeData {
    /** 天数 */
    days: number;
    /** * Number of hours */
    hours: number;
    /** * Number of minutes */
    minutes: number;
    /** * number of seconds */
    seconds: number;
    /** * milliseconds */
    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(a);this.endTime = endTime;
        this.step = step;

        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;
        }

        this.remainTime = Math.max(this.endTime - Date.now(), 0);

        this.emit(CountdownEventName.RUNNING, this.parseRemainTime(this.remainTime), this.remainTime);

        if (this.remainTime > 0) {
            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, }; }}Copy the code
  1. Write a cached decorator


const cacheMap = new Map(a);export function EnableCache(target: any, name: string, descriptor: PropertyDescriptor) {
    const val = descriptor.value;
    descriptor.value = async function(. args: any) {
        const cacheKey = name + JSON.stringify(args);
        if(! cacheMap.get(cacheKey)) {const cacheValue = Promise.resolve(val.apply(this, args)).catch((_) = > cacheMap.set(cacheKey, null));
            cacheMap.set(cacheKey, cacheValue);
        }
        return cacheMap.get(cacheKey);
    };
    return descriptor;
}

Copy the code

“Feel free to discuss in the comments section.”

Hope to finish watching friends can give a thumbs-up, encourage once