前端系统学习 4. TS

基础知识

基础类型: number string boolean array object undefined void

1. enum 枚举的使用

2. type 和 interface 区别

3. 联合类型 | 类似的概念

如果 type D = A | B | C

  1. D 必须含有 A B C 中一个的所有成员
  2. D 的其他成员必须是 A B C 中的成员

type A = {
  a: number,
  b: number,
  c: number
}
type B = {
  a: number,
  d: number,
  e: number
}
type C = {
  a: number,
  f: number,
  g: number
}
type D = A | B | C

const sth: D = {
  a: 1,
  b: 1,
  c: 1,
  d: 1,
  g: 1,
  // h: 1
}

4. 交叉类型 & 类似的概念

5. typeof 可以基于已有的变量/函数获得他的类型

function toArray(x: number): Array<number> {
  return [x]
}

type Func = typeof toArray

6. keyof 获取一个对象当中的 key

interface Person {
  name: number,
  age: number
}

type XX = keyof Person // 'name' | 'age'

const x: XX = 'age'

7. in 遍历枚举类型

type Keys = "a" | "b" | 'c'

type Obj = {
  [key in Keys]: number
}

const obj: Obj = {
  a: 1,
  b: 1, 
  c: 1,
  // d: 1
}

8. extends

泛型:对于类型的参数

interface A<T> {
  a: T
}

const b: A<number> = {
  a: 1
}

extends 用来约束泛型的类型

interface ILengthwise {
  length: number
}

function log<T extends ILengthwise> (arg: T): T {
  return arg
}

log({length: 1, width: 1})

9. Partial

将类型成员都变为可选

interface XX {
  name: string,
  sex: string
}

type AA = Partial<XX>
/**
 * {
 *  name?: string,
 *  sex?: string
 * }
 */

10. Required

将类型成员都变为必选

面试题及实战

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

1.1 TypeScript是 JavaScript 的加强版,它给 JavaScript 添加了可选的静态类型和基于类的面向对象编程,它拓展了 JavaScript 的语法。
1.2 TypeScript 是纯面向对象的编程语言,包含类和接口的概念。
1.3 TS 在开发时就能给出编译错误,而 JS 错误则需要在运行时才能暴露
1.4 作为强类型的语言,可以明确知道数据的类型。代码可读性极强,方便多人协作。
1.5 TS 中有很多方便的特性,如可选链。

  1. type 和 interface 的区别

重点:type 用来描述类型,interface 用来描述接口

2.1 都可以描述一个对象或函数

interface User {
  name: string
  age: string
}

interface SetUser {
  (name: string, sex: string): void
}

type User {
  name: string,
  age: string
}

type SetUser = (name: string, age: string) => void

2.2 都允许拓展

interface 和 type 都可以拓展,而且两者可以相互拓展。效果差不多,但是两者语法不同

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

2.3 只有 type 能做的

type 可以声明基本类型别名,联合类型,元组等类型

// 基本类型别名
type Name = string

// 联合类型
interface Dog {
  wong()
}
interface Cat {
  miao()
}
type Pet = Dog | Cat

// 具体定义数组每个位置的类型
type PetList = [Dog, Cat]

// 获取一个 js 变量的类型时,使用 typeof
const div = document.createElement('div')
type D = typeof div
  1. 如何基于一个已有的类型,扩展出一个大部分内容相似,但是有部分区别的类型?

首先可以通过 Pick 和 Omit

interface User {
  name: string,
  sex: string,
  age: number
}

type BB = Pick<User, 'name' | 'age'>

其次可以通过 Partial、Required

再者可以通过泛型。

  1. 写一个 routerHelper
import { Dictionary } from 'vue-router/types/router';
import Router, { RoutePath } from '../router'

type BaseRouteParam = Dictionary<string>

export interface IndexParam extends BaseRouteParam {
  index: string
}

export interface AboutParam extends BaseRouteParam {
  about: string
}

export interface UserParam extends BaseRouteParam {
  user: string
}

export interface ParamMap {
  [RoutePath.Index]: IndexParam,
  [RoutePath.About]: AboutParam,
  [RoutePath.User]: UserParam,
} 

class RouterHelper {
  static push<T extends RoutePath> (path: T, query: ParamMap[T]) {
    return Router.push({
      path, query
    })
  }
}

export default RouterHelper
  1. 写一个 CountDown
import { EventEmitter } from 'eventemitter3'

enum CountDownStatus {
  running,
  stoped
}

export enum CountDownEventName {
  START = 'start',
  RUNNING = 'running',
  STOP = 'stop'
}

type CountDownEventMap = {
  [CountDownEventName.START]: [],
  [CountDownEventName.STOP]: [],
  [CountDownEventName.RUNNING]: [RemainTimeData, number],
}

interface RemainTimeData {
  hours: number,
  minutes: number,
  seconds: number,
  counts: number
}

export default class CountDown extends EventEmitter<CountDownEventMap> {
  private static COUNT_TICKS = 10
  private static SECOND_TICKS = 100 * CountDown.COUNT_TICKS
  private static MINITE_TICKS = 60 * CountDown.SECOND_TICKS
  private static HOUR_TICKS = 60 * CountDown.MINITE_TICKS

  private status: CountDownStatus = CountDownStatus.stoped
  private remainTime = 0
  private endTime = 0
  private step = 100
  private timer = 0

  constructor(endTime: number, step: number) {
    super()

    this.endTime = endTime
    this.step = step

    this.start()
  }

  public start() {
    if (this.status === CountDownStatus.stoped) {
      this.status = CountDownStatus.running
      this.emit(CountDownEventName.START)
      this.countdown()
    }
  }

  public stop() {
    if (this.status === CountDownStatus.running) {
      this.status = CountDownStatus.stoped
      this.emit(CountDownEventName.STOP)
      clearTimeout(this.timer)
    }
  }

  private countdown() {
    this.emit(CountDownEventName.RUNNING, this.parseRemainTime(), this.remainTime)
    this.timer = requestAnimationFrame(() => {
      this.remainTime = Math.max(this.endTime - Date.now(), 0)
      if (this.remainTime > 0) {
        this.countdown()
      } else {
        this.stop()
      }
    });
  }

  private parseRemainTime() {
    let time = this.remainTime

    const hours = Math.floor(time / CountDown.HOUR_TICKS)
    time = time % CountDown.HOUR_TICKS
    const minutes = Math.floor(time / CountDown.MINITE_TICKS)
    time = time % CountDown.MINITE_TICKS
    const seconds = Math.floor(time / CountDown.SECOND_TICKS)
    time = time % CountDown.SECOND_TICKS
    const counts = Math.round(time / CountDown.COUNT_TICKS)

    return {
      hours, minutes, seconds, counts
    }
  }


}
  1. tsc 原理

源码 => 扫描器(Scanner)=> Token 流 => 解析器(Parser) => AST =>

  1. 类型检查
  2. 生成 js 代码
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342