Charlie
2022/10/12阅读:89主题:蔷薇紫
typescript学习经验分享
typescript学习经验分享
Q1: 为什么要学习typescript?
-
typescript更可靠
❝ts可以进行静态类型检测,可以在开发阶段进行告警,就是我们平时看到的红色波浪线,据不完全统计,这让至少 10% 的 JavaScript 错误(主要是一些低级错误)能在开发阶段就被发现并解决。当 TypeScript 类型检测能力覆盖到整个文件、整个项目代码后,任意破坏约定的改动都能被自动检测出来(即便跨越多个文件、很多次传递),并提出类型错误。因此,你可以放心地修改、重构业务逻辑,而不用过分担忧因为考虑不周而犯下低级错误。接手复杂的大型应用时,TypeScript 能让应用易于维护、迭代,且稳定可靠,也会让你更有安全感。
❞
-
typescript正在成为主流
❝相比竞争对手 Facebook 的 Flow 而言,TypeScript 更具备类型编程的优势,而且还有 Microsoft、Google 这两家国际大厂做背书。另外,越来越多的主流框架(例如 React、Vue 3、Angular、Deno、Nest.js 等)要么选用 TypeScript 编写源码,要么为 TypeScript 提供了完美的支持。随着 TypeScript 的普及,TypeScript 在国内(国内滞后国外)成了一个主流的技术方向,国内各大互联网公司和中小型团队都开始尝试使用 TypeScript 开发项目,且越来越多的人正在学习和使用它。
❞
❝题外话: typescript是图灵完备的
❞
❝图灵完备是指在可计算性理论里,如果一系列操作数据的规则(如指令集、编程语言、细胞自动机)可以用来模拟单带图灵机
❞
Q2: 怎么入门typescript?
-
我是通过看这个文档对ts基本语法有所认知的,TypeScript 入门教程, 并在此处进行练习
-
原始数据类型
// 1. 字符
const _string: string = ''
// 2. 数值
const _number: number = 1
// 3. 布尔
const _boolean: boolean = true
// 4. symbol
const _symbol: symbol = Symbol('symbol')
// 5. undefined
const _undefined:undefined = undefined
// 6. null
const _null: null = null
// 7. void
function fn (): void {}
-
其他类型
-
never: never 处理 TS 类型系统的最底层
❝1.无法将任意类型的数据赋值给 never 类型可以将 never 类型赋值给任意其他类型
❞
❝2.理解:never 表示啥也不是,所以,无法给 never 设置任何内容
❞
❝3.理解:never 处于最底层,相当于任何类型的子类型,所以,可以赋值给其他任何类型
❞
❝4.比如,‘a’ 字面量就是string 的子类型 let s: string = ‘a’
❞
const _never: never = '' as never
let _any: any
_any = _never
type isTrue = never extends any ? true : false
-
unknown: unknown 处于 TS 类型系统的最顶层
❝1.可以将任意类型的数据赋值给 unknown 类型
❞
❝2.无法将 unknown 类型赋值给任意其他类型
❞
❝3.简单来说:unknown 类型可以接受任意类型,但是无法赋值给其他类型
❞
❝4.理解:unknown 表示不确定,不确定就可以表示任意类型,既然可以是任意类型,所以可以接受任意类型的数据
❞
❝5.理解:unknown 表示不确定,不确定就可以表示任意类型,既然可以是任意类型,所以就无法赋值给一个特定的类型
❞
function fn (p: unknown): void { /* ts中用void表达没有任何返回的值的函数。*/
console.log(typeof p)
}
-
联合类型: 联合类型(Union Types)表示取值可以为多种类型中的一种。
let myFavoriteNumber: string | number;
myFavoriteNumber = 'seven';
myFavoriteNumber = 7;
-
对象的类型——接口
interface Person {
readonly id: number // 只读
name: string
age: number
gender?: string // 可选
[propName: string]: any // 任意属性
}
const tom: Person = {
id: 1,
name: 'Tom',
age: 25,
gender: 'male'
};
-
数组的类型
let fibonacci1: number[] = [1, 1, 2, 3, 5]; // 「类型 + 方括号」表示法
let fibonacci2: Array<number> = [1, 1, 2, 3, 5]; // 数组泛型
interface NumberArray {
[index: number]: number;
} // 用接口表示数组
let fibonacci3: NumberArray = [1, 1, 2, 3, 5];
-
泛型 泛型(Generics)是指在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定类型的一种特性。
function createArray<T>(length: number, value: T): Array<T> {
let result: T[] = [];
for (let i = 0; i < length; i++) {
result[i] = value;
}
return result;
}
createArray(3, 'x'); // ['x', 'x', 'x']
❝泛型约束§ 在函数内部使用泛型变量的时候,由于事先不知道它是哪种类型,所以不能随意的操作它的属性或方法:
❞
interface Lengthwise {
length: number;
}
function loggingIdentity<T extends Lengthwise>(arg: T): T { // extends 可以对泛型进行约束它还有其他作用
console.log(arg.length);
return arg;
}
❝泛型接口
❞
interface IPerson<T> {
[K: string]: T
}
const a: IPerson<string> = {
name: 'charlie'
}
Q3: 怎么开始高级玩法?
-
首先把TypeScript 中文网里的高级类型给看了,对高级类型有所了解,然后可以在b站看看一些up的分享视频,可以搜索“typescript类型体操”,对ts高级玩法有所了解
-
extends 用法
// 1. 接口继承
interface T1 {
name: string
}
interface T2 {
type: string
}
interface T3 extends T1, T2 {
gender: string
}
const t3: T3 = {
name: '',
type: '',
gender: '',
};
// 2. 条件判断
/* 条件判断就是用来判断一个类型是不是可以分配给另一个类型,这在写高级类型的时候非常有用。 */
type str1 = 'fish' | 'animal'
type str2 = 'fish'
// type str2 符合 str1的约束条件,所以可以赋值给后者,所以判断为true
type canBeTrue = str2 extends str1 ? true : false
const a: canBeTrue = true;
// 3. 范型条件判断(包含never知识点)
type P<T> = T extends 'x' ? string : number
// 范型条件判断中的extends符合分配律规则,'x'可以 就是string, 'y'不可以就是number
type A1 = P<'x' | 'y'> // string | number
// never是任何类型的子类型
type A2 = never extends 'x' ? string : number // string
// never也是没有联合项可以分配的联合类型,所以P的表达式其实根本就没有执行,所以A3的定义也就类似于永远没有返回的函数一样,是never类型的
type P1<T> = T extends 'x' ? string : number
type A3 = P<never> // never
// 4. 泛型约束
type IOb<T extends string | number> = {
[K: string]: T
} // 这里T必须是 string 或者 number
const p: IOb<string> = {
key: 'a'
}
-
& 用法
❝交叉类型是将多个类型合并为一个类型。 这让我们可以把现有的多种类型叠加到一起成为一种类型,它包含了所需的所有类型的特性。 例如, Person & Serializable & Loggable同时是 Person 和 Serializable 和 Loggable。 就是说这个类型的对象同时拥有了这三种类型的成员。
❞
-
as 用法: 类型重映射、断言
❝遍历可迭代对象进行过滤
❞
❝as还可以用于 断言
❞
-
怎么遍历对象的属性?
type T = {
a: string
b: number
}
type O = {
[K in keyof T]: number
}
-
怎么遍历数组?
type arr = ['a', 'b', 'c']
type O = {
[K in Arr[number]]: number
}
-
infer 和 ... 的用法
type A<Arr> = Arr extends [infer F, ...infer Rest] ? F : never
Q4: 怎么加深巩固?
-
可以把这个项目down下来TypeScript 类型体操, 然后在本地进行练习
❝我们来做4个easy和4个medium的类型体操吧
❞
参考资料:
1.TypeScript 入门教程 https://ts.xcatliu.com/basics/
2.TypeScript 中文网 https://www.tslang.cn/docs/home.html
3.TypeScript 英文官网(更全面) https://www.typescriptlang.org/
4.TypeScript 类型体操 https://github.com/type-challenges/type-challenges
5.关注这些个up主 https://space.bilibili.com/175301983/?spm_id_from=333.999.0.0
https://space.bilibili.com/1376675981/?spm_id_from=333.999.0.0
作者介绍