一、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 * 1000, 10);
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