ts常用基础及面试题

1,202 阅读3分钟

一、ts的基础知识

1、基础类型:

  • number string boolean array object undefined void
  • enum 枚举
  • type interface
  • 联合类型 | (联合类型一次只能用一种类型)
  • 交叉类型 & (交叉类型每次都是多个类型的合并类型)
  • typeof 可以用来获取一个变量声明或者对象的类型
  • keyof 获取key
  • in 遍历枚举类型
  • extends 用来约束泛型
  • Partial<> 将<>中的参数都变成可选项
  • Required<> 将<>中的参数都变成必选项
// 枚举
enum ActionType {
   Run,
   eat
}

// type
type Action = 'eat' | 'run'
const a:Action = ''; //会报错,只能在上面的两个值中选择一个
interface BaiduResponse{
    name:string;
    height:number;
}
axios.get<BaiduResponse>().then();

// interface接口
interface A{
    name:string;
}
interface B{
    sex:number;
}
function test(a:A|B){
}
test(sex:0, name:'aaa')

// extends拓展
interface ILengthwise{
    length:number
}
function loggingIdentity<T extends ILengthwise>(arg:T):T{
    return arg;
}
loggingIdentity({length:10,value:1})//必须要传这种类型的值

二、常见面试题

1、你觉得ts的好处是什么?

1、ts是js的加强版,給js添加了可选的静态类型或者基于类的面向对象编程,ts的功能給js只多不少;

2、ts是面向对象的语言,包含了类、接口等概念;

3、ts在开发时就能给出编译错误,js错误只能在运行时体现

4、作为强类型语言,可以明确知道所有数据的类型

2、type和interface的区别

1、用interface来描述数据结构,用type描述类型

2、相同点: 都能用来描述函数和对象 都允许拓展extends

3、不相同:type用法较多,可以声明联合类型 type name = string type a=b | c type petList = [dog, pet]

3、如何基于一个已有的类型,扩展出一个大部分内容相似,但是部分区别的类型?

首先可以通过Pick(选择需要的)和Omit(排除不需要的)

interface Test{
    name:string,
    sex:number,
    height:string
}

type Sex = Pick<Test, 'sex'>; // 选中一个
type WithoutSex = Omit<Test, 'sex'>; //排除一个

再者可以通过泛型。

4、什么是泛型,泛型的具体使用

泛型是指在定义函数、接口或类的时候,不预先指定具体的类型,使用时再去指定类型的一种特性。

可以把泛型理解为代表类型的参数。

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

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

const a:TestA = {
    userId:'111'
}
const b:TestB = {
    userId:222
}

三、实战

写一个倒计时countdown.ts
import {EventEmitter} from 'eventemitter3';

export interface RemainTimeData{
    days:number;
    hours:number;
    minutes:number;
    seconds:number;
    count:number;
}

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 step;number;
    private status:CountdownStatus.stoped;
    constructor(endTime:number, step:number = 1e3){
        super();
        this.endTime = endTime;
        this.step = step;
    }
}
    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,
        };
    }
使用文件home.vue中:
public created() {

        const countdown = new Countdown(Date.now() + 60 * 60 * 100010);

        countdown.on(CountdownEventName.RUNNING(remainTimeData) => {

            const { hours, minutes, seconds, count} = remainTimeData;

            this.timeDisplay = [hours, minutes, seconds, count].map(fillZero).join(':');

        });
}

ts原理:

  • 源码
  • 扫描器scanner
  • token流
  • 解析器parse
  • ast