TypeScript 极简教程,极速入门!

大家好,我是暮云,在前端开发不断演进的今天,TypeScript 已经逐渐从"可选技能"变成了许多团队的"默认要求"。

如果你在使用 JavaScript,却时常被一些难以定位的 bug 困住,或者在维护大型代码时感到混乱不堪,那么 TypeScript 将是一个非常值得学习的工具

这篇文章非常的简洁,用最短的文字介绍了TypeScript的各种语法,如果你会使用简单的TypeScript,又不是很熟练,也可以看一看,尤其是对象类型三元运算符索引访问infer推断扩展这几个标题下的内容,可能会有新的收获,也可以把这篇文章当作一个文档,当某些语法忘记了可以来看一下

接下来我们便进入正文,首先,我们在学习TypeScript时不要把它当成JavaScript的扩展,而是要把它当成一个新的语言来学习,这样的话你就会更容易的理解范型typeofkeyof等关键字语法了

基础类型

首先列举一些 TypeScript 的数据类型有:stringnumberbooleannullundefinedanyunknownvoidneverobject

这些就不一一介绍了,只看一些不常见的

unknown:表示未知类型,使用前必须明确判断类型

void:表示一个函数无返回值

never:表示一个不可能的值

这些类型在后边都会详细介绍

字面类型

字面类型是指:一个值本身就是一个类型

示例:

'hello' -> { 'hello' }

1 -> { 1 }

->前面表示的是类型,后面大括号中包着的便是符合类型的值,后面的例子都用这种形式表示

联合类型

联合类型使用 | 运算符进行组合

示例:

1 | 2 -> { 1, 2 }

string | number -> { 'a', 'b', ..., 1, 2, ... }

子类型

当A类型中所有值都存在于B中,那么就可以说这个A是B的子类型

示例:

true extends boolean

string extends any

元组类型

元组是什么:元组是一个固定长度,固定类型顺序的数组

示例:

typescript 复制代码
type T1 = [boolean, string]
const a: T1 = [true, 'a']

对象类型

对象类型:用于描述一个对象应该拥有哪些属性,以及这些属性的类型是什么

当我们声明一个对象类型时,只要对象 至少满足声明的属性要求 ,就被视为合法类型,额外的属性是允许的(注意,额外的属性是允许的!)

示例:

{ a: boolean } -> { { a: true }, { a: false }, { a: true, b: 1 } }

这个示例里面的{ a: true, b: 1 }是符合{ a: boolean }类型的

想必大家在写下面这段代码时都会遇到类型报错的问题

typescript 复制代码
const obj: { a: boolean } = {
    a: true,
    b: 1
}

报错:"b"不在类型"{ a: boolean; }"中

如果你是这样写的话,就完全不会有这种问题

typescript 复制代码
const t = {
    a: true,
    b: 1
}
const obj: { a: boolean } = t

这是为什么呢?下面我来讲一下原因

在ts中,字面量赋值会触发更严格的额外属性检查 ,因为你如果写字面量的话很有可能会写错单词,比如将method写成mothod,一旦这个属性写错,是很难被发现的bug,所以TS 触发额外属性检查,是为了阻止低级错误

交叉类型

交叉类型用 & 拼接,它表示同时符合这些类型的值

示例:

{ a: number } & { b: number } -> { a: number, b: number }

类型别名

类型别名使用 type 关键字声明

示例:

typescript 复制代码
type T = 1 | 2 | 3
const a:T = 1 // 还可以是2 3

范型

范型可以让我们在定义函数、接口、类时,不预先限定具体类型,而是在使用时再传入需要的类型

示例:

typescript 复制代码
type I<T> = T
const a:I<number> = 1

范型就像是我们在写 TypeScript 版的函数,调用传参

typeof

typeof 可以用来获取变量或对象的类型信息,用于类型推断或类型保护

示例:

typescript 复制代码
const str = "hello"
type T = typeof str // T -> string

as const

有时候我们希望对象或数组的每个属性都被推断为字面量类型而不是普通类型 ,这时可以使用 as const

示例:

typescript 复制代码
const obj = { a: 1, b: 2 } as const
// obj 的类型是 { readonly a: 1; readonly b: 2 }

const arr = [1, 2, 3] as const
// arr 的类型是 readonly [1, 2, 3]

它的作用就是:

  1. 把对象/数组里的值变成字面量类型
  2. 所有属性变成 readonly,不能被修改

unknown 和 any

  • any :表示任意类型,关闭类型检查,随意使用,但容易出错
  • unknown :表示未知类型,使用前必须进行类型判断,更安全
typescript 复制代码
let x: any = 1
x.toFixed() // 没问题

let y: unknown = 1
y.toFixed() // 报错,必须先判断类型

let y: unknown = 1
if(typeof y === 'number') y.toFixed() // 没问题

keyof

keyof 用于获取某个对象类型的所有键,返回一个联合类型

typescript 复制代码
type Obj = {a: number, b: string}
type Keys = keyof Obj // 'a' | 'b'

索引访问

索引访问类型可以通过类型获取对象属性类型,非常方便

typescript 复制代码
type Obj = {a: number, b: string}
type A = Obj['a'] // number
type B = Obj['b'] // string
type C = Obj[keyof Obj] // number | string

type Arr = [string,number,boolean]
type D = Arr[0] // string
type E = Arr[number] // string | number | boolean

映射

映射类型用于 [K in ...] 遍历键并创建新的对象类型

typescript 复制代码
type Keys = 'a' | 'b' | 'c'
type Obj = {[K in Keys]: number}
// Obj -> {a:number, b:number, c:number}

这个语法把他当成js中的遍历是不是就很好理解了

三元运算符

TypeScript 支持条件类型,其语法类似 js 的三元运算符

typescript 复制代码
type IsString<T> = T extends string ? true : false
type A = IsString<'hello'> // true
type B = IsString<123>     // false

// 当对联合类型进行求值时,TypeScript 会分别处理每个成员,然后将结果合并在一起
type C = IsString<('1'|1)> // boolean

// 使用 never 过滤掉不想要的分支
type Filter<T, Match> = T extends Match ? T : never;
type D = Filter<number | string, string> // string
type E = Filter<1 | 'a' | 'b', string> // 'a' | 'b'

注意:每个类型都被视为自身的子类型

typescript 复制代码
string extends string ? true : false  // true

infer推断

infer 用于条件类型中推断类型,特别适合提取类型信息

typescript 复制代码
type FlattenArray<T> = T extends (infer Item)[] ? Item : T
type A = FlattenArray<number[]> // number

type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never
type R = ReturnType<() => string> // string
  1. 第一个例子很好理解,我们来看一下第二个例子
  2. 首先给 ReturnType 传递参数:() => string ,一个函数类型
  3. 然后 T extends (...args: any[]) => infer R ,判断这个T,也就是传递的那个函数是否属于(...args: any[]) => infer Rinfer 推断出返回值为 string ,所以 R 的值为 string
  4. 最终判断为 true ,返回 string 类型

扩展

ok,我们把基本 TypeScript 的语法学完了,下面写两个实用的示例

筛选

typescript 复制代码
type Pick<T, K extends keyof T> = { [P in K]: T[P] }
type A = Pick<{a: number, b: string}, 'a'> // { a: number }

never的用法

typescript 复制代码
type Fruit = 'apple' | 'banana'

function eat(fruit: Fruit) {
  if (fruit === 'apple') {
    console.log('吃苹果')
  } else if (fruit === 'banana') {
    console.log('吃香蕉')
  } else {
    // 这里是不可能发生的分支
    const _check: never = fruit
    console.log(_check)
  }
}

如果将来 fruit 的值新增了一个,那么这段程序就会报错,这样你就会知道这里需要添加新的分支了

相关推荐
妙码生花18 小时前
从 PHP 到 AI + Golang,程序员自救转型手记(二十六):icon 组件封装
前端·vue.js·typescript
PBitW1 天前
为什么vite中TS报错,可以继续运行?Webpack不行?💡
前端·typescript
敖行客 Allthinker1 天前
前端调试实战:DevTools调试工具 + 二分定位Bug法全总结
前端·typescript·chrome devtools
不瘦80斤不改名1 天前
HalfCart:基于LBS的1\.5km本地拼单系统全栈实践与踩坑复盘
python·docker·typescript·pycharm
濮水大叔2 天前
在大型 Vue 项目中,如何有效管理复杂的状态?“散装版” vs “套装版”
前端·vue.js·typescript
谷哥的小弟3 天前
TypeScript数组类型
javascript·typescript
退休倒计时3 天前
【每日一题】LeetCode 199. 二叉树的右视图 TypeScript
算法·leetcode·typescript
前端之虎陈随易3 天前
编程语言级别的Skill市场,AI Agent 的未来形态
前端·vue.js·人工智能·typescript·node.js
后台开发者Ethan4 天前
类型分类、联合类型、交叉类型
typescript
鹰影474 天前
一款AI笔记助手和远程同步的markdown笔记idea-note
人工智能·笔记·rust·typescript·react