也许跟大家不太一样,我是这么用TypeScript来写前端的

更新日期: 2023-09-15阅读: 686标签: TypeScript

一、当前一些写前端的骚操作

先罗列一下见到过的一些写法吧:)

1. interface(或Type)一把梭

掘金上很多文章,一提到 TypeScript,那不得先用 interface 或者 type 来声明个数据结构吗?像这样:

type User = {
nickname: string
avatar?: string
age: number
}

interface User {
nickname: string
avatar?: string
age: number
}

然后其他方法限制下入参类型,搞定,我掌握了 TypeScript 了,工资不得给我涨3000???

这里说明一下, 我司 不允许 直接使用 interface type 来定义非装饰器参数和配置性参数之外其他 任何数据类型。

2. 类型体操整花活

要么把属性整成只读了,要么猪狗类型联合了,要么猪尾巴搞丢了,要么牛真的会吹牛逼了。

类型体操确实玩出了很多花活。 昨天说过了:TypeScript最好玩的就是类型体操, 也恰好是最不应该出现的东西

3. hook 的无限神话

不知道什么时候开始,hook 越来越流行。 听说不会写 hook 的前端程序员,已经算不上高阶程序员了, 不 use 点啥都展示不出牛逼的水平。

4. axios 拦截大法好

随便搜索一下 axios 的文章, 没有 拦截器 这个关键词的文章都算不上 axios 的高端用法了。


二、 我们一些不太一样的前端骚操作

昨天的文章有提到一些关于在前端使用 装饰器 来实现一些基于配置的需求实现, 今天其实想重点聊一聊如何在前端优雅的面向对象。

写过 Java、SpringBoot、JPA 等代码的后端程序员应该非常熟悉的一些概念:

  • 抽象: 万物都可抽象成相关的类和对象
  • 面向对象: 继承、封装、多态等特性的面向对象设计思维
  • 切面: 没有什么是切一刀解决不了的,如果一刀不行, 那就多来几刀。
  • 注解: 没有什么常量是不能使用注解来配置的, 也没有什么注解是切面想切还能躲得掉的
  • 反射: 没有什么是暴力拿取会失败的, 即使失败也没有异常是丢不出来的
  • 实体: 没有什么是不能抽象到实体上的, 万物皆唯一。
  • 很多: 还有很多,以上描述比较主观和随意。

于是我们开始把后端思维往前端来一个个的转移:)

1. 抽象和面向对象

与后端的交互数据对象、 请求的api接口都给抽象到具体的类上去,于是有了:

Service API请求类

abstract class AbstractService{
// 实现一个抽象属性 让子类们实现
abstract baseUrl!: string

// 再实现一些通用的 如增删改查之类的网络请求
// save()

// getDetail()

// deleteById()

// select()

// page()

// disabled()

// ......
}

Entity 数据实体基类

abstract class AbstractBaseEntity<S extends AbstractService> {
abstract service: AbstractService

// 任何数据都是唯一的 ID
id!: number

// 再来实现一些数据实体的更新和删除方法
save(){
await service.save(this.toJson())
Notify.success("新增成功")
}

delete(){
service.deleteById(this.id)
Notify.success("删除成功")
}
// ......
}

子类的实现:

class UserEntity extends AbstractUserEntity<UserService>{
service = new UserService()

nickname!: string
age!: number
avatar?: string

// 用户是否成年人
isAdult(): boolean{
return this.age >= 18
}
}

View 视图调用

<template>
<el-input v-model="user.nickname"/>
<el-button @click="onUserSave()">创建用户</el-button>
</template>
<script setup lang="ts">
const user = ref(new UserEntity())
async function onUserSave(){
await user.save()
}
</script>


2. 装饰器/切面/反射

装饰器部分的话,昨天的文章有提到一些了,今天主要所说反射和切面部分。

在 TypeScript 中, 其实装饰器本身就可以理解为一个切面了, 这里与 Java 中还是有很多不同的, 但概念和思维上是基本一致的。

反射 Reflect 是 TypeScript 中比较坑的一个存在, 目前主要是依赖 reflect-metadata 这个第三方库来实现, 将一些元数据存储到 metadata 中, 在需要使用的时候通过反射的方式来获取。 可以参考这篇文章:TypeScript 中的元数据以及 reflect-metadata 实现原理分析

在实际使用中, 我们早前用的是 class-transformer 这个库, 之前我对这个库的评价应该是非常高的: “如果没有 class-transformer 这个库, TypeScript 狗都不写。”

确实很棒的一个库,但是在后来,我们写了个通用的内部框架, 为了适配 微信小程序端 以及 uniapp 端, 再加上有一些特殊的业务功能以及 class-transfromer 的写法和命名方式我个人不太喜欢的种种原因, 我们放弃了这个库, 但我们仿照了它的思想重新实现了一个内部使用的库,做了一些功能的阉割和新特性的添加。

核心功能的一些说明

通过反射进行数据转换

如将后端API返回的数据按照前端的数据结构强制进行转换, 当后端数据返回乱七八糟的时候,保证前端数据在使用中不会出现任何问题, 如下 demo
class UserEntity {
@Type(String) phone!: string;
@Type(RoleEntity) roleInfo!: RoleEntity:
@Type(DeptEntity) @List @Default([]) deptInfoList!: DeptEntity[]
@Type(Boolean) @Default(false) isDisabled!: boolean
}

通过反射进行配置的存储和读取

这个在昨天的文章中有讲到一部分, 比如配置表单、表格、搜索框、权限 等


3. 再次强调面向对象

为了整个前端项目的工程化、结构化、高度抽象化,这里不得不再次强调面向对象的设计:)

这是个拼爹的社会

一些通用的功能,一旦有复用的可能, 都可以考虑和尝试让其父类进行实现, 如需要子类传入一些特性参数时, 可以使用抽象方法或抽象属性(这可是Java中没有的)来传入父类实现过程中需要的特性参数。

合理的抽象分层

将一些特性按照不同的抽象概念进行组合与抽离,实现每个类的功能都是尽可能不耦合,实现类的单一职责。如存在多继承, 在考虑实现类的实现成本前提下,可考虑抽象到接口 interface 中。

还有很多,有空再一一列举

4. 严格但又有趣的 tsdoc

我们先来看一些注释的截图吧:)




一些详细的注释、弃用的方法、选填的参数、传入参数后可能影响或依赖的其他参数,在注释里写好玩的 emoji或者图片,甚至是 直接在注释里写调用 demo, 让调用方可以很轻松愉快的对接调用, 玩归玩, 确实对整体项目的质量有很大的帮助。


三、 写在最后

中午跟同事吃饭聊了聊现在国内大前端的一个状态, 当时聊到一个关键词 舒适区, 还有前端整个技术栈过于灵活的一些优缺点, 几个大老爷们都发出了一些感慨, 如果前端能够更标准化一些, 像 Java 一样, 说不定前端还能上升几个高度。

That's all, 今天水的文章到此结束。

作者:Hamm
链接:https://juejin.cn/post/7259562014417813564

链接: https://fly63.com/article/detial/12513

用TypeScript弥补Elm和JavaScript之间的差距

近些日子,我使用了新语言编程,从JavaScript,切确地说是Elm,转成TypeScript。在本文中,我将继续深挖一些我非常喜欢的TypeScript特性。

Typescript 和 Javascript之间的区别

TypeScript 和 JavaScript 是目前项目开发中较为流行的两种脚本语言,我们已经熟知 TypeScript 是 JavaScript 的一个超集,但是 TypeScript 与 JavaScript 之间又有什么样的区别呢?

Nerv_一款类 React 前端框架,基于虚拟 DOM 技术的 JavaScript(TypeScript) 库

Nerv_是一款由京东凹凸实验室打造的类 React 前端框架,基于虚拟 DOM 技术的 JavaScript(TypeScript) 库。它基于React标准,提供了与 React 16 一致的使用方式与 API。

TypeScript_TS系列之高级类型

交叉类型:将多个类型合并为一个类型、联合类型:表示取值可以为多种类型中的一种、混合类型:一个例子就是,一个对象可以同时做为函数和对象使用,并带有额外的属性、类型断言:可以用来手动指定一个值的类型

TypeScript 在 JavaScript 的基础上的改动

在做比较大的,多人合作的项目的时候,TypeScript会更加地适合,这得益于它的可读性,面向对象性以及易于重构的特点。但如果只是自己做小程序,不需要太多人参与的时候,JavaScript则会更加简单。

5分钟了解TypeScript

有两种方式安装TypeScript,如何创建第一个TypeScript文件,在TypeScript中,可以使用interface来描述一个对象有firstName和lastName两个属性,TypeScript支持JavaScript的新功能,其中很重要的一个功能就是基于类的面向对象编程

如何编写 Typescript 声明文件

使用TypeScript已经有了一段时间,这的确是一个好东西,虽说在使用的过程中也发现了一些bug,不过都是些小问题,所以整体体验还是很不错的。有关TypeScript声明类型声明相关的目前就总结了这些比较常用的

谷歌为何会选用TypeScript?

谷歌在很早之前就张开双臂拥抱 Web 应用程序,Gmail 已经发布 14 年了。当时,JavaScript 的世界是疯狂的。Gmail 工程师不得不为 IE 糟糕的垃圾回收算法捏一把汗,他们需要手动将字符串文字从 for 循环中提取出来,以避免 GC 停顿

为什么要学习Typescript 语言呢?Typescript 开发环境安装

TypeScript是一种由微软开发的自由和开源的编程语言。它是JavaScript的一个超集,TypeScript是JavaScript类型的超集,它可以编译成纯JavaScript。TypeScript可以在任何浏览器、任何计算机和任何操作系统上运行,并且是开源的。

使用TypeScript两年后-值得吗?

差不多两年前,我在一个创业团队中开始了一个全新的项目。用到的全都是类似Microservices,docker,react,redux这些时髦的东西。我在前端技术方面积累了一些类似的经验

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!