TypeScript,从0到入门带你进入类型的世界(二)

简介: 下面的文章中将讲解我对 TS 入门的一些归纳总结。一起来了解一下吧!

六、枚举


1、普通枚举

枚举常使用于我们在程序中需要做权限管理或者做判断时等各种场景。枚举比较简单,下面直接用代码演示:

enum Direction{
    Up,
    Down,
    Left,
    Right
}
console.log(Direction.Up) //0
console.log(Direction.Down) //1
console.log(Direction.Left) //2
console.log(Direction.Right) //3
console.log(Direction[0]) //Up
复制代码

除了以上基本用法外,我们还可以给枚举赋值:

enum Direction{
    Up = 10,
    Down,
    Left,
    Right
}
console.log(Direction.Up) //10
复制代码


2、常量枚举

我们来定义一个常量,与 enum 做判断。

enum Direction{
    Up = 'Up',
    Down = 'Down',
    Left = 'Left',
    Right = 'Right'
}
//定义一个常量,直接与enum做判断
const value = 'Up';
if(value === Direction.Up){
    console.log('go Up!') // go Up!
}
复制代码

使用常量枚举可以有效地提升性能,常量会内联枚举的任何用法,而不会把枚举变成任意的 Javascript 代码。

这样一说,那是不是所有的 enum 都可以使用常量枚举呢?答案自然是否定的。

枚举的值有两种类型,一种是常量值枚举(constant),一种是计算值枚举(computed)。只有常量值枚举可以进行常量枚举,而计算值枚举不能进行常量枚举


七、泛型


接下来我们来讲 TypeScript 中最难的一部分,泛型。


1、普通泛型

泛型,即 generics 。指在定义函数、接口或类的时候,我们不预先指定类型,而是在使用的时候再指定类型和其特征。

可以理解为,泛型就相当于一个占位符或者是一个变量,在使用时再动态的填入进去,填进去以后既可以来确定我们的类型值。

接下来我们用代码来演示一下:

function echo<T>(arg: T): T{
    return arg
}
const result = echo(true)
console.log(result) // true
复制代码

我们通过 <> 来定义一个未知的泛型,之后当我们给它赋值时,就可以对应值的数据类型。


现在我们再用泛型来定义一个 number 类型的数组。具体代码如下:

// 早期定义一个number类型的数组
let arr: number[] = [1, 2, 3]
// 用泛型定义一个number类型的数组
let arrTwo: Array<number> = [1, 2, 3]
复制代码

假如我们现在要调换两个元素的位置,那么用泛型我们可以这么实现。具体代码如下:

function swap<T, U>(tuple: [T, U]): [U, T]{
    return [tuple[1], tuple[0]]
}
const result2 = swap(['abc', 123])
console.log(result2[0]) //123
console.log(result2[1]) //abc
复制代码

通过泛型,我们就顺利调换了两个元素的位置。


2、约束泛型

在泛型中使用 extends 关键字,就可以让传入值满足我们特定的约束条件,而不是毫无理由的随意传入。

比如,我们想要让我们定义的内容是一个数组,我们可以这么处理。具体代码如下:

function echoWithArr<T>(arg: T[]): T[]{
    console.log(arg.length)
    return arg
}
const arrs = echoWithArr([1, 2, 3])
复制代码

这样,就把 arrs 定义为一个数组。


假设我们现在想要让我们定义的内容可以访问到 length 方法,那么我们需要加一点佐料。具体代码如下:

interface IWithLength{
    length: number
}
function echoWithLength<T extends IWithLength>(arg: T): T{
    console.log(arg.length)
    return arg
}
const str = echoWithLength('str')
const obj = echoWithLength({ length: 10, width: 20 })
const arr2 = echoWithLength([1, 2, 3])
复制代码

通过 extends 关键字来继承特定的 interface ,使得我们定义的内容 strobjarr2 达到可以访问length方法的目的。

通过以上举例,我们可以知道,泛型可以用来灵活的约束参数的类型,参数不需要是个特别死板的类型,而可以通过我们的约束来达到我们想要的目的。


3、泛型在类和接口中的使用


(1)泛型在类中的使用

class Queue<T>{
    private data = []
    push(item: T){
        return this.data.push(item)
    }
    pop(): T{
        return this.data.shift()
    }
}
// 确定这是一个number类型的队列
const queue = new Queue<number>()
queue.push(1)
console.log(queue.pop().toFixed())
复制代码


(2)泛型在接口中的使用

interface KeyPair<T, U>{
    key: T
    value: U
}
let kp1: KeyPair<number, string> = {key: 1, value: 'str'}
let kp2: KeyPair<string, number> = {key: 'str', value: 2}
复制代码

通过以上代码演示可以发现,泛型就像是创建了一个拥有特定类型的容器,就仿佛给一个容器贴上标签一样。


八、类型别名


1、类型别名

类型别名,即 type aliase 。类型别名可以看作是一个快捷方式,可以把一个写起来很繁琐的类型创建一个简单的写法。比如:

//用以下这种写法,每次都要写一长串的(x: number, y: number) => number
let sum: (x: number, y: number) => number
const result = sum(1, 2)
//用type给类型进行别名
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
复制代码


2、字符串字面量

字符串字面量,指可以提供一系列非常方便使用的常量写法比如:

const str: 'name' = 'name'
const number: 1 = 1
type Direction = 'Up' | 'Down' | 'Left' | 'Right'
let toWhere: Direction = 'Left'
复制代码


3、交叉类型

交叉类型,使用 type 这个扩展对象的一种方式。比如:

interface IName{
    name: string
}
type IPerson = IName & {age: number}
let person: IPerson = {name: 'monday', age: 18}
复制代码


九、声明文件


我们在写ts时,难免会有遇到要引入第三方库的时候。这个时候就需要ts来做特殊处理。主要有以下两种做法:


1、 .d.ts 文件引入

假设我们要引入JQuery库来使用,那么我们可以在外部新增一个 JQuery.d.ts 文件,文件内代码如下:

declare var JQuery: (selector: string) => any;
复制代码

之后便可以在我们定义的 ts 文件下引用 JQuery 相关库的内容。比如:

jQuery('#foo')
复制代码


2、npm安装

我们也可以安装对应的第三方库的 npm 包。假如我们现在要引入一个 JQuery 库,那么我们可以这么处理。

npm install --save @type/jquery
复制代码


十、内置类型


我们在写 ts 代码时,其实不知不觉已经使用了很多的内置对象。对象呢,是指根据标准(标准指 ECMADOM 等标准),在全局作用域 global 上面存在的对象。那我们在运行 tsc 时,这些内置的对象就会被当作附加的礼物给程序加载进行。接下来我们来体会一下几种常见的内置对象。

全局对象:

// global object 全局对象
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和BOM对象:

// DOM 和 BOM
let body = document.body
let allLis = document.querySelectorAll('li')
allLis.keys()
document.addEventListener('click', e => {
    e.preventDefault()
})
复制代码

功能性类型:

// Utility Types 功能性类型
interface IPerson{
    name: string
    age: number
}
let monday: IPerson = {name: 'monday', age: 20}
//可选属性
type IPartial = Partial<IPerson>
let monday2: Ipartial = {name: 'monday'}
//移除某一个属性
type Omit = Omit<IPerson, 'name'>
let monday3: Omit = {age: 20}
复制代码


十一、结束语


关于 ts 的入门讲到这里就结束啦!希望大家能对 ts 有一个简单的认识!

相关文章
|
2月前
|
前端开发 JavaScript 安全
TypeScript在React Hooks中的应用:提升React开发的类型安全与可维护性
【7月更文挑战第17天】TypeScript在React Hooks中的应用极大地提升了React应用的类型安全性和可维护性。通过为状态、依赖项和自定义Hooks指定明确的类型,开发者可以编写更加健壮、易于理解和维护的代码。随着React和TypeScript的不断发展,结合两者的优势将成为构建现代Web应用的标准做法。
|
30天前
|
JavaScript
TypeScript——不能将类型“HTMLElement | null”分配给类型“HTMLElement”
TypeScript——不能将类型“HTMLElement | null”分配给类型“HTMLElement”
26 4
|
11天前
|
JavaScript 前端开发 编译器
Angular 与 TypeScript 强强联手太厉害啦!强类型编程带来巨大开发优势,快来一探究竟!
【8月更文挑战第31天】作为一名前端开发者,我致力于探索各种技术框架以提升开发效率与代码质量。近期深入研究了Angular与TypeScript的结合,体验到强类型编程带来的显著优势。Angular是一款强大的前端框架,而TypeScript则是由微软开发的一种强类型语言,为JavaScript增添了静态类型检查等功能。
20 0
|
1月前
|
JavaScript 编译器
typescript 解决变量多类型访问属性报错--工作随记
typescript 解决变量多类型访问属性报错--工作随记
|
21天前
|
JavaScript 前端开发 安全
TypeScript:解锁JavaScript的超级英雄模式!类型系统如何化身守护神,拯救你的代码免于崩溃与混乱,戏剧性变革开发体验!
【8月更文挑战第22天】TypeScript作为JavaScript的超集,引入了强大的类型系统,提升了编程的安全性和效率。本文通过案例展示TypeScript如何增强JavaScript:1) 显式类型声明确保函数参数与返回值的准确性;2) 接口和类加强类型检查,保证对象结构符合预期;3) 泛型编程提高代码复用性和灵活性。这些特性共同推动了前端开发的标准化和规模化。
43 0
|
29天前
|
JavaScript
TypeScript——Record类型
TypeScript——Record类型
31 0
|
1月前
|
JavaScript 前端开发 编译器
Typescript 回调函数、事件侦听的类型定义与注释--拾人牙慧
Typescript 回调函数、事件侦听的类型定义与注释--拾人牙慧
|
2月前
|
JavaScript 开发者 索引
TypeScript接口与类型别名:深入解析与应用实践
【7月更文挑战第10天】TypeScript的接口和类型别名是定义类型的关键工具。接口描述对象结构,用于类、对象和函数参数的形状约束,支持可选、只读属性及继承。类型别名则为复杂类型提供新名称,便于重用和简化。接口适合面向对象场景,类型别名在类型重用和复杂类型简化时更有优势。选择时要考虑场景和灵活性。
|
2月前
|
JavaScript 前端开发 索引
TypeScript 的数组类型
TypeScript 的数组类型
32 1
|
3月前
|
JavaScript 前端开发 IDE
TypeScript中的声明文件(.d.ts):扩展类型系统
TypeScript的`.d.ts`声明文件为JS库提供类型信息,增强IDE支持,如自动完成和类型检查。通过声明合并,可在全局作用域定义类型。示例包括为`my-library`创建声明模块,导出函数和接口。声明文件通常存于`@types`或指定`typeRoots`。用于旧JS代码的类型注解,如`myGlobalObject`。学习更多,参阅TypeScript官方文档。分享你的TS声明文件经验!
101 1