程序员必备技能之---Typescript
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