[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