typescript - 我想要注意的点

本贴最后更新于 1645 天前,其中的信息可能已经事过景迁

学习 TS 有一段时间了,目前很多的一些项目都开始往 TS 转,在写的过程中总会遇到一些大大小小的问题,然后也没人一起学习与帮助,还是蛮吃力的。

所以将在整体的学习过程中,我认为比较重要的点都在这记录下来,以后遇到的一些问题都会往这里补充吧,如果大家有想一起分享的,都可以写在评论区,然后我再补充到文章中,咱们社区也能建立起好的前段氛围呀huaji trollface

函数剩余参数的类型定义

function push(array: any[], ...items: any[]) { items.forEach(function(item) { array.push(item); }); } let a = []; push(a, 1, 2, 3);

函数中重载的类型定义

function reverse(x: number | string): number | string { if (typeof x === 'number') { return Number(x.toString().split('').reverse().join('')); } else if (typeof x === 'string') { return x.split('').reverse().join(''); } } # 输入 numbernumber,输入 stringstring,但是上面显然不能满足 function reverse(x: number): number; function reverse(x: string): string; function reverse(x: number | string): number | string { if (typeof x === 'number') { return Number(x.toString().split('').reverse().join('')); } else if (typeof x === 'string') { return x.split('').reverse().join(''); } }

类型断言

#1.as 类型 #2. <类型>值 # 作用1:确定联合类型中的类型 interface Cat { name: string; run(): void; } interface Fish { name: string; swim(): void; } function getName(animal: Cat | Fish) { return animal.name; } function isFish(animal: Cat | Fish) { # 这里会报错的 if (typeof animal.swim === 'function') { return true; } return false; } ----- 需要了解返回的是那个类型 function isFish(animal: Cat | Fish) { # 利用 as 表示此时的 animal 为 Fish 类型 if (typeof (animal as Fish).swim === 'function') { return true; } return false; }

双重断言

  • 任何类型可以被断言为 any
  • any 可以被断言为任何类型

所以可以利用 as any as Foo 将任何一个类型断言为另一个类型

interface Cat { run(): void; } interface Fish { swim(): void; } function testCat(cat: Cat) { return (cat as any as Fish); } # 当然使用双重断言是非常不友好的,除非迫不得已,尽量别使用

类型断言解决泛型

function getCacheData(key: string): any { return (window as any).cache[key]; } interface Cat { name: string; run(): void; } const tom = getCacheData('tom') as Cat; tom.run(); ---- 类型断言去掉 any function getCacheData<T>(key: string): T { return (window as any).cache[key]; } interface Cat { name: string; run(): void; } const tom = getCacheData<Cat>('tom'); tom.run();

字符串约束取值

有时候,比如某个参数只能是 a 或者 b 的时候

# 首先可以这么写 let func = (str: 'top' | 'end') => {} # 同时也可以字符串字面量类型 # 字符串字面量类型用来约束取值只能是某几个字符串中的一个。 type Flow = 'top' | 'end' let func = (str: Flow) => {} # 还可以使用类型别名 type Flow = { top: string, end: string } let func = (str: keyof Flow) => {}

元组与数组泛型的联合类型

元素可以确定数据类型,但是不能超过范围,可以理解元组可以固定数组长度,超出范围并不能保证其类型。

# 基本定义 let tom: [string, number]; tom = ['Tom', 25]; tom.push('male'); tom.push(true); // Argument of type 'true' is not assignable to parameter of type 'string | number'. # 数组泛型与元组的去呗 type Name = string|number let arr: Array<Name> = ['Tom', 25] arr = [25, 'Tom'] let tom: [string, number]; tom = ['Tom', 25]; // true tom = [25, 'Tom'] // false Type 'string' is not assignable to type 'number'.(2322)

快速生成一个 ts 模板库

npm install -g tsdx

命名空间的作用( namespace

类似于闭包的作用(立即执行函数):作用域的另一种抽象,为了防止相同名称带来的冲突。

// 命名空间 namespace Utility { export const log = (msg:string) => console.log(msg) export const error = (msg:string) => console.error(msg) } Utility.log('hello') Utility.error('error')

箭头函数泛型怎么写

# <T> 不写 reverse<T> 而是 reverse = <T>()=>{} const reverse = <T>(items: T[]): T[] => { let toreturn = [] for(let i = items.length - 1; i>=0; --i) { toreturn.push(items[i]) } return toreturn } const sample = [1, 2, 3] let reversed = reverse(sample) console.log(reversed) const strs = ['b', 'a', 'c'] let reversed1 = reverse<string>(strs) console.log(reversed1)

交叉类型怎么写

比如需要将两个对象进行合并,这时候需要使用交叉类型,类似于 Java 一样的交叉类型

const extend = <T extends object, U extends object>(a:T, b:U):T&U=> { const result = <T&U>{} for(let id in a) { // 注意这里需要加上 <T> (<T>result)[id] = a[id] } for(let id in b) { // 注意这里需要加上 <T> if(result.hasOwnProperty(id)) (<U>result)[id] = b[id] } return result } const x = extend({a:'hello'}, {a:1,b:42})

类型不存在怎么办

比如 Window 之类的都是存在,加入某个公共的类不存在怎么办呢,可以创建一个 global.d.ts 声明一些需要的类型。

重载解决可选参数声明

function padding(a: number, b?: number, c?: number, d?: any) { if (b === undefined && c === undefined && d === undefined) { b = c = d = a; } else if (c === undefined && d === undefined) { c = a; d = b; } return { top: a, right: b, bottom: c, left: d }; } # ------- // 重载 function padding(all: number):any; function padding(topAndBottom: number, leftAndRight: number):any; function padding(top: number, right: number, bottom: number, left: number):any; // Actual implementation that is a true representation of all the cases the function body needs to handle function padding(a: number, b?: number, c?: number, d?: number) { if (b === undefined && c === undefined && d === undefined) { b = c = d = a; } else if (c === undefined && d === undefined) { c = a; d = b; } return { top: a, right: b, bottom: c, left: d }; } padding(1); // Okay: all padding(1, 1); // Okay: topAndBottom, leftAndRight padding(1, 1, 1, 1); // Okay: top, right, bottom, left padding(1, 1, 1); // Error: Not a part of the available overloads

nerver 与 void

  • void 表示的是返回为空(undefined),实际上是有返回值的
  • never 是一个不包含值的类型,这意味着具有这种返回类型的函数永远不能正常返回。这意味着要么抛出异常,要么无法终止。
# void returns void, never never returns. function do(): never { while (true) {} } const error = (msg) => throw new Error(msg); // never const fail = () => error('failed here.'); // never
  • TypeScript
    23 引用 • 19 回帖 • 2 关注
  • 前端

    前端技术一般分为前端设计和前端开发,前端设计可以理解为网站的视觉设计,前端开发则是网站的前台代码实现,包括 HTML、CSS 以及 JavaScript 等。

    245 引用 • 1338 回帖
  • 分享

    有什么新发现就分享给大家吧!

    248 引用 • 1794 回帖 • 1 关注
1 操作
Rabbitzzc 在 2020-10-27 10:52:07 更新了该帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...