沐光

记录在前端之路的点点滴滴

TS 高级技巧

前言

假期在家中无意间刷到了一篇 TS 技巧的文章,自己尝试了一下,觉得确实挺不错的,因此这里做一些记录。

活用提示

在使用 ts 的 interface 做定义声明时,一般写注释时都习惯性的使用单行注释 // ...,虽然在看对应的 interface 时我们能知道是什么内容,但是在使用时往往只有个光秃秃的声明,后期维护时会感觉特别鸡肋:

单行注释

但是如果这样写注释的话,在注释的呈现上会更利于阅读:

多行注释

对返回参数、组件传参声明 等会经常去查阅的 ts 声明部分,可使用多行注释的写法,让使用体验更友好。

interface & type

TypeScript 中有两种定义接口类型的方法,分别是: interface(接口)type alias(类型别名),它们之间是能够自身继承、相互继承的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// interface 继承 interface
interface Item {
name: string;
}

interface SubItem extends Item {
age: number;
}

// type alias 继承 type alias
type Shape = { name: string };
type SubShape = Shape & { age: number };

// interface 继承 type alias
type Data = { name: string };
interface SubData extends Data {
age: number;
}

// type alias 继承 interface
interface List {
name: string;
}
type SubList = List & { age: number };

这两者使用上特别相似,但也稍微有些不一样的地方

1. 写法不同

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// interface(偏向于:类、实例)
interface IProps {
name: string;
funcA: (param1: number) => void;
}

// type alias(偏向于:字面量形式的值/对象、函数)
type data = { name: string };
type funcA = (param1: number) => void;

// 函数的 ts 声明的三种写法
const func1: funcA = p => {}; // type 声明
const func2: IProps['funcA'] = p => {}; // interface 声明
const func3 = (p: number): void => {}; // 内联式声明

目前项目中使用面向对象的写法会多一些,因此 类、实例 的出现比例会打一些,对于单独 .ts 文件内声明的函数可用 type 做声明会更方便一些

2. 其它不同

其它部分就直接粘贴看到的文章了,就不赘述了

其它区别

typeof

这一点先前确实没关注过,不过对于有默认值的类型,确实会节省不少时间:

1
2
3
4
5
6
7
8
9
10
const defaultProps = {
/** 这里写属性的提示:姓名 */
name: '',
};

/** 这里写整体的提示 */
type IProps = typeof defaultProps;

// 这里 hover 上时会有提示
const myData: IProps = defaultProps;

keyof

这个单独来看用途可能不是很大,但是封装通用函数时,没有这个可能问题很大:

按照以前的写法,所获得的值会丢失类型,这 ts 就有些尴尬:

any 写法

使用 keyof 方法改写后,我们来看看效果:

keyof 写法

这样我们便能够从方法中推断出对应对象的类型了,确实方便了很多。

参考文章