每个开发人员都应该知道的 TypeScript 技巧

这段时间运用typescript有了更深入的了解,在此之前,一直使用的javascript开发项目,最近在做的一个项目恰巧用到了,然后就开启了边学边做的历程,经过这段时间的摸索,也总结一些技巧,以下总结的几点:

1. satisfies用于更好的类型推断

该运算符验证表达式是否与类型匹配,同时保留字面量类型,这对于需要兼顾类型安全性和精确推断的配置对象尤为重要。

ts 复制代码
// 不使用
const Config1: Record<string, string | number> = {
    port: 3000,
    host: 'localhost'
}

// 使用
const Config2 = {
    port: 3000,
    host: 'localhost'
} satisfies Record<string, string | number>

2. 不可变类型的Const断言

添加as const到对象后,Typescript会将所有属性变为只读属性,并推断出具体的类型,这对于不可更改配置对象尤为重要

ts 复制代码
const User = {
    name: 'zhansan'
    age: 18,
    sex: 'man'
} as Const

3. 模板字符串字面量类型

模板字面量类型允许你创建与特定字符串匹配的类型,适合用于API端点,事件名称和任何结构化字符串

ts 复制代码
 type EventName = `on${Capitalize<string>}`
 // 正确示范:'onChange' 'onHandle' onClick'
 // 错误示范:'change' 'handle' 'click'
 
 type Method = 'GET' | 'POST' | 'DELETE' | 'PUT'
 type Endpoint = `/api/${string}`
 type Route = `${Method} ${Endpoint}`
 // 正确示范:GET /api/users
 // 错误示范:GET /users
 
 function MakeRoute(route: Route): void {
     return route
 }
 
 MakeRoute('GET /api/users')

4. 自定义类型的关键字定义

在创建函数时指定对象类型

ts 复制代码
function isString(value: unKnown) value is string {
    return typeof value === 'string'
}

5. 使用索引访问类型

使用索引访问类型

使用括号表示法访问类型定义,这可以保持类型的DRY原则,并在源类型发生变化保持更新。

ts 复制代码
 type User = {name: string, age: number}
 type UserName = User['name'] // string

6. 三元运算符动态判断对象类型

使用条件判断对象类型,常见的使用三元运算符判断

ts 复制代码
    type isArray<T> = T extends any[] ? true : false
    
    // 提取数据元素类型
    type Flatten<T> = T extends Array[infer U] ? U : T
    type Flatten1 = Flatten<string[]> // string
    type Flatten2 = Flatten<number> // number
    
    // 其他案列
    type ApiResponse<T> = T extends {error: string} ? {success: false, error: string : {success: true, data: T}

7. 函数重载,可以更好的得到编辑器的提示

php 复制代码
使用函数重载,获得更好的提示与准确的类型保护
```ts
function getUserById(id: string): User {}

// override
function getUserById(id: string): User {
    // 写逻辑判断
    const user = {}
    return user
}
```

8. keyof类型约束

可以使用keyof限制传递类型,可以更好避免类型推断错误

ts 复制代码
  function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
     return obj[key]
  }

9. 模块扩充

根据需要扩展现有模块类型,通常是向窗口添加属性或者第三方库

ts 复制代码
 declare global {
      interface Window {
          analytics: AnalyticsClient
      }
 }

10. 类型导入

ts 复制代码
import type { User } from './types'

11. 断言函数

创建断言函数和缩小类型的函数,如果断言失败,函数将抛出异常,这对于在运行时验证数据并同时保证Typescript正常运行。

ts 复制代码
function assertDefined<T>(value: T | undefined): asserts value is T {
    if (value === undefined) {
        throw new Error('value is undefined')
    }
}

// 自定义类型谓词 (asserts value is T)是语法
// 使用
function processUser(user: User | undefined) {
    assertDefined(user)
    console.log(user.name)
}

12. 名义类型模式(品牌类型模式)

这种模式是将相同类型但是又需要有区别人为制造差异化,定义一个_brand虚拟属性,从而实现类型定义更准确。

ts 复制代码
type UserId = string & {_brand: 'UserId'}
type PostId = string & {_brand: 'PostId'}

function createUserId(id: string): UserId {
    return id as UserId
}

function createPostId(id: string): PostId {
    return id as PostId
}

const userId: UserId = createUserId('12345')
const postId: PostId = createPostId('12345')

function getUserById(id: UserId) { /** */ }

getUserById(userId) // 正确
getUserById(postId) // 报错

13. 使用枚举

ts 复制代码
const enum status = {
    Error = 'error'
    Success = 'success'
    Fail = 'fail'
}

14. 组合交叉类型

将多个类型合并为一个类型,对于合并不相关的类型比extends好用

ts 复制代码
type Name =  string
type Age = number
type Worker = {
    address: string,
    job: string
}

type User = Name & Age & Worker

总结

运用好类型判断,不仅能节省排除错误的时间,还能提高开发效率,虽然定义类型是一件痛苦的事情,但是后续项目维护起来那就是非常丝滑的操作了。后续如果有补充再继续完善!

相关推荐
一生躺平的仔7 小时前
TypeScript入门(九)装饰器:TypeScript的"元编程超能力"
typescript
MiyueFE8 小时前
让我害怕的 TypeScript 类型 — — 直到我学会了这 3 条规则
前端·typescript
前端拿破轮8 小时前
😭😭😭看到这个快乐数10s,我就知道快乐不属于我了🤪
算法·leetcode·typescript
奋飛11 小时前
TypeScript系列:第六篇 - 编写高质量的TS类型
javascript·typescript·ts·declare·.d.ts
BillKu10 天前
Vue3 + TypeScript + xlsx 导入excel文件追踪数据流转详细记录(从原文件到目标数据)
前端·javascript·typescript
小Lu的开源日常10 天前
Drizzle vs Prisma:现代 TypeScript ORM 的深度对比
数据库·typescript·前端框架
Shixaik11 天前
配置@为src
typescript·前端框架
BillKu11 天前
Vue3 + TypeScript合并两个列表到目标列表,并且进行排序,数组合并、集合合并、列表合并、list合并
vue.js·typescript·list
ze_juejin11 天前
Typescript中的继承示例
前端·typescript