likes
comments
collection
share

程序员必备技能之---Typescript

作者站长头像
站长
· 阅读数 72

Typescript

2022 年什么会火?什么该学?本文正在参与“聊聊 2022 技术趋势”征文活动 」

为什么要使用 typescript

程序更容易理解

  • 问题:函数或者方法输入输出的参数类型,外部条件等
  • 动态语言的约束:需要手动调试等过程
  • 有了Typescript:代码本身就可以回答上述问题

更少的错误

  • 编译期间能够发现大部分错误
  • 杜绝一些比较常见的错误

非常好的包容性

  • 完全兼容 Javascript
  • 第三方库可以单独编写类型文件
  • 大多数项目都支持 typescipt

一点小缺点

  • 增加了一些学习成本
  • 短期内增加了一些开发成本

数据类型

原始数据类型

let isDone: boolean = false

let age: number = 10

let firstName: string = 'viking'
let message: string = `Hello, ${firstName}`

let u: undefined = undefined
let n:null = null

let num: number = undefined

Any类型

let notSure: any = 4
notSure = 'maybe a string'
notSure = true

notSure.myName
notSure.getName()

数组和元组

数组

let arr: number[] = [1,2,3]
arr.push(3)

// arguments类数组 IArguments类型,不是Array
function test(){
    console.log(arguments);
    arguments.length
    arguments[0]
}

元组

将不同数据类型的元素放在一起

let user: [string, number] = ['abc', 20]
user.push('1212')	只能push已有类型

接口 Interface

interface IPerson{
    readonly id: number;    // 只读属性
    name: string
    age: number
    address?: string    // 可选属性
}

let lihua: IPerson = {
    id: 1,
    name: 'lihua',
    age: 20
}

函数

function add(x: number, y: number, z?: number): number {
    if (typeof z === 'number') {
        return x + y + z
    } else {
        return x + y
    }
}
add(1, 2)
add(1, 2, 3)
const add =  (x: number, y: number, z?: number): number => {
    if (typeof z === 'number') {
        return x + y + z
    } else {
        return x + y
    }
}

interface ISum{
    (x: number, y: number, z?: number):number
}
let add2: ISum = add

类型推论

联合类型

let numberOrString: number | string
numberOrString.toString()	// 联合类型的共有属性和方法

类型断言

使用非共有属性和方法时,利用 as 关键字,将变量看作为某个类型,或利用 typeof 判断类型

// union types
let numberOrString: number | string

function getLength(input: string | number): number {
  const str = input as string
  if (str.length) {
    return str.length
  } else {
    const number = input as number
    return number.toString().length
  }
}

//type guard
function getLength2(input: string | number): number {
  if (typeof input === 'string') {
    return input.length
  } else {
    return input.toString().length
  }
}

枚举 enums

// 数字枚举,枚举成员会被赋值为从第一个值(默认为0)开始递增的数字
enum Direction {
    Up,
    Down,
    Left,
    Right,
}
console.log(Direction.Up)   // 0
console.log(Direction[0])   // Up

// 字符串枚举
enum Direction {
    Up = 'UP',
    Down = 'DOWN',
    Left = 'LEFT',
    Right = 'RIGHT',
}
const value = 'UP'
if (value === Direction.Up) {
    console.log('go up!')
}

// 常量枚举,可减少性能
const enum Direction {...}

泛型 Generics

泛型基础

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

function echo<T>(arg: T): T {
  return arg
}

const result = echo(true)

function swap<T, U>(tuple: [T, U]): [U, T] {
  return [tuple[1], tuple[0]]
}
const result2 = swap(['string', 123])

约束泛型

在函数内部使用泛型变量的时候,由于事先不知道它是哪种类型,所以不能随意的操作它的属性或方法

Typescript中的extends关键字-技术圈 (proginn.com)

interface IWithLength {
  length: number
}

function echoWithLength<T extends IWithLength>(arg: T): T {
  console.log(arg.length)
  return arg
}

const str = echoWithLength('str')	// 要有length属性
const obj = echoWithLength({ length: 10, width: 10})
const arr2 = echoWithLength([1, 2, 3])

类中应用

class Queue<T> {
  private data = [];
  push(item: T) {
    return this.data.push(item)
  }
  pop(): T {
    return this.data.shift()
  }
}
const queue = new Queue<number>()
queue.push(1)
console.log(queue.pop().toFixed())

接口中应用

interface KeyPair<T, U> {
  key: T
  value: U 
}
let kp1: KeyPair<number, string> = { key: 1, value: "string"}
let kp2: KeyPair<string, number> = { key: 'str', value: 2 }
let arr: number[] = [1,2,3]
let arrTwo: Array<number> = [1,2,3]		// Array内置泛型

类型别名 和 交叉类型

类型别名

// type aliase
let sum: (x: number, y: number) => number
const result = sum(1,2)
type PlusType = (x: number, y: number) => number
let sum2: PlusType
const result2 = sum2(2, 3)

type StrOrNumber = string | number
let result3: StrOrNumber = '123'
result3 = 123

const str: 'name' = 'name'
const number: 1 = 1
type Directions = 'Up' | 'Down' | 'Left' | 'Right'
let toWhere: Directions = 'Left'

交叉类型

interface IName {
  name: string
}
type IPerson = IName & { age: number }
let person: IPerson = { name: '123', age: 123 }

内置类型

//global objects
const a: Array<number> = [1,2,3]
const date = new Date()
date.getTime()
const reg = /abc/
reg.test('abc')

//build-in object
Math.pow(2, 2)

//DOM and BOM
let body = document.body
let allLis = document.querySelectorAll('li')
allLis.keys()

document.addEventListener('click', (e) => {
  e.preventDefault()
})

TypeScript: Documentation - Utility Types (typescriptlang.org)

//Utility Types
interface IPerson {
  name: string
  age: number
}
let viking: IPerson = { name: 'viking', age: 20 }
type IPartial = Partial<IPerson>	// 可选类型
let viking2: IPartial = { name: 'viking' }
type IOmit = Omit<IPerson, 'name'>	// 忽略name类型
let viking3: IOmit = { age: 20 }
转载自:https://juejin.cn/post/7063427394513666085
评论
请登录