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)

泛型组件

相关推荐
熊的猫36 分钟前
JS 中的类型 & 类型判断 & 类型转换
前端·javascript·vue.js·chrome·react.js·前端框架·node.js
瑶琴AI前端1 小时前
uniapp组件实现省市区三级联动选择
java·前端·uni-app
会发光的猪。1 小时前
如何在vscode中安装git详细新手教程
前端·ide·git·vscode
我要洋人死2 小时前
导航栏及下拉菜单的实现
前端·css·css3
科技探秘人2 小时前
Chrome与火狐哪个浏览器的隐私追踪功能更好
前端·chrome
科技探秘人2 小时前
Chrome与傲游浏览器性能与功能的深度对比
前端·chrome
JerryXZR3 小时前
前端开发中ES6的技术细节二
前端·javascript·es6
七星静香3 小时前
laravel chunkById 分块查询 使用时的问题
java·前端·laravel
q2498596933 小时前
前端预览word、excel、ppt
前端·word·excel
小华同学ai3 小时前
wflow-web:开源啦 ,高仿钉钉、飞书、企业微信的审批流程设计器,轻松打造属于你的工作流设计器
前端·钉钉·飞书