Typescript实用指南

[TOC]

没有TS时的困扰

less 复制代码
张三: 你知道下面的这个test方法要如何传参吗?
胖虎: 传a,b两个参数
张三: 具体呢?你知道a,b是什么类型吗?
胖虎: 你一没注释,二又看不到代码具体内容,我怎么知道a,b什么类型?你是在为难我胖虎啊
张三: 要注释? 没问题,继续往下看
js 复制代码
function test(a,b){
    ...
}
less 复制代码
张三: 再看看这个,注释,代码都有了,告诉我a,b如何传参
胖虎: 找茬呢,这注释有和没有有区别吗?还有这代码,还要我通读,还要我根据代码推敲这个参数的意思和类型,不想写就别写啊
js 复制代码
/**
* @params {Object} a 第一个参数
* @params {Object} b 第二个参数
*/
function test(a,b){
    const {flag,good} = b
    ...省略若干代码
    if(b.test){
        ...省略若干代码
    }
}

没错这就是前端项目在没有TS时,大概率会遇到的问题,别人写的方法具体如何调用?后端接口返回的参数到底是什么接口? 不知道,在不运行到具体代码行,不一行行阅读源码,大概率是不知道的

基础

与JS基本数据类型对应的TS类型定义

字符串

ts 复制代码
let str:string = ''

数值

ts 复制代码
let num:number = 1

布尔值

ts 复制代码
let flag:boolean = true

数组

ts 复制代码
const arr1: Array<string> = []
const arr2: Array<string|number> = []
const arr3: [string,number] = ['a',1]

日期

ts 复制代码
const date: Date = new Date()

null与undefined

ts 复制代码
const x1: null = null
let x2: undefined;

symbol

ts 复制代码
const sym: Symbol = Symbol()
const symb: Symbol = Symbol('abc')

Map类型

ts 复制代码
const map = new Map<string,number>()

对象

ts 复制代码
const obj: Record<string, any> = {}

interface Person {
  name: string
  age: number
}

const p:Person = {
    name:"张三",
    age:12
}

函数

ts 复制代码
function test(a: number, b: number): number {
  return a + b
}
ts 复制代码
function test(a: string, b: string): number
function test(a: number, b: number): number

function test(a: number | string, b: number | string): number {
  const numA: number = typeof a === 'string' ? Number(a) : a
  const numB: number = typeof b === 'string' ? Number(b) : b
  return numA + numB
}

test('1', '2')
test(4, 3)
ts 复制代码
type TestFun = (a: number, b: number) => number
const fun: TestFun = (a, b) => {
  return a + b
}
ts 复制代码
interface TestFun {
  (x: number, y: number): number
}
const fun: TestFun = (x, y) => {
    return x+y
}

复合类型

ts 复制代码
interface PartA {
  name: string
  fatherName: string
}
interface PartB {
  age: number
  male: boolean
}

type PartC = PartA & PartB
type PartD = PartA | PartB

const partC: PartC = {
  name: '',
  fatherName: '',
  age: 0,
  male: false
}

const partD: PartD = {
  name: '',
  fatherName: ''
}

获取对象中所有key作为类型定义

ts 复制代码
interface PartA {
  name: string
  fatherName: string
}

type PartAKeys = keyof PartA

const keyFahter: PartAKeys = 'fatherName'
const keys: PartAKeys = 'name'

抽取特定接口定义的部分属性,作为一个新类型

ts 复制代码
interface Person {
  name: string
  age: number
  male: boolean
}

// 使用Person接口的name,male形成一个新接口
type NewPerson = Pick<Person, 'name' | 'male'>

const person: Person = { name: '张三', age: 12, male: true }
const newPerson: NewPerson = { name: '张三', male: true }

排除特定接口定义的部分属性,作为一个新类型

ts 复制代码
interface Person {
  name: string
  age: number
  male: boolean
}

// 将Person接口,排除age属性之后,形成一个新接口
type NewPerson = Omit<Person, 'age'>

const person: Person = { name: '张三', age: 12, male: true }
const newPerson: NewPerson = { name: '张三', male: true }

以特定接口为基础进行扩展

ts 复制代码
interface Person {
  name: string
  male: boolean
}

interface NewPerson extends Person {
  age: number
}

const p: Person = {
  name: '',
  male: true
}

const p1: NewPerson = {
  name: '',
  male: true,
  age: 0
}

泛型

指定this类型

ts 复制代码
type Service<R, P extends unknown[]> = (...args: P) => Promise<R>
function wrapper<R, P extends unknown[]>(service: Service<R, P>) {
  return function (this: any, ...args: P) {
    const method = service.bind(this)
    return method(...args)
  }
}

function test(a: number, b: number): Promise<number> {
  return Promise.resolve(a + b)
}

const wrapperTest = wrapper(test)

;(async () => {
  console.log(await wrapperTest(1, 2))
})()
ts 复制代码
/**
 *
 * @param this 指定this类型,必须为第一个参数
 * @param str 从这个参数开始,才是这个方法的实际参数
 */
function doAdd(this: Plus, str: string) {
  const ret = this.a + this.b
  console.log(str, ret)
}
class Plus {
  a: number = 0
  b: number = 0

  constructor(a: number, b: number) {
    this.a = a
    this.b = b
  }

  add = doAdd
}

new Plus(1, 3).add('hello')

any, unknow

any和unknow都表示任意类型,但unknow要求,在使用unknow声明的变量时,必须先转换为某个具体的类型

void, never

可变参数类型

不确定的可变参数类型通过此种方式指定

ts 复制代码
type Service<R, P extends unknown[]> = (...args: P) => Promise<R>
function wrapper<R, P extends unknown[]>(service: Service<R, P>) {
  return function (this: any, ...args: P) {
    const method = service.bind(this)
    return method(...args)
  }
}

function test(a: number, b: number): Promise<number> {
  return Promise.resolve(a + b)
}

const wrapperTest = wrapper(test)

;(async () => {
  console.log(await wrapperTest(1, 2))
})()

禁止TS报错

ts 复制代码
单行忽略
// @ts-ignore

忽略全文
// @ts-nocheck

取消忽略全文
// @ts-check
ts 复制代码
/* eslint-disable */
const watermark = require("watermark-dom"); // @ts-ignore
/* eslint-enable */

便捷操作

ts 复制代码
const obj: Record<'x1' | 'x2' | string, string | number> = {
  x1: '你好',
  x2: '世界',
  name: '张三'
}

实际项目快速应用TS定义

从json字符串生成TS

JSON to TS - Visual Studio Marketplace

从swagger生成TS

tswagger - Visual Studio Marketplace

swagger-to-ts-fix - Visual Studio Marketplace

swagger-to-ts - Visual Studio Marketplace

JS To TS - Visual Studio Marketplace

vue3项目中的TS

组件事件: defineEmits

TypeScript 与组合式 API | Vue.js (vuejs.org)

泛型组件

相关推荐
hackeroink2 小时前
【2024版】最新推荐好用的XSS漏洞扫描利用工具_xss扫描工具
前端·xss
迷雾漫步者3 小时前
Flutter组件————FloatingActionButton
前端·flutter·dart
向前看-4 小时前
验证码机制
前端·后端
燃先生._.5 小时前
Day-03 Vue(生命周期、生命周期钩子八个函数、工程化开发和脚手架、组件化开发、根组件、局部注册和全局注册的步骤)
前端·javascript·vue.js
高山我梦口香糖5 小时前
[react]searchParams转普通对象
开发语言·前端·javascript
m0_748235246 小时前
前端实现获取后端返回的文件流并下载
前端·状态模式
m0_748240256 小时前
前端如何检测用户登录状态是否过期
前端
black^sugar6 小时前
纯前端实现更新检测
开发语言·前端·javascript
寻找沙漠的人7 小时前
前端知识补充—CSS
前端·css