工作中的那点事之 TypeScript


工作中的那点事之 TypeScript

as const处理 ts 类型误差

ts 的联合类型使用就经常容易出现类型误差。

1
2
3
4
5
6
7
8
9
10
11
export type Config = {
type: "c" | "l" | "z";
name: string;
}[];

const config: Config = [
{
type: "c",
name: "赤蓝紫",
},
];

上面的代码是没有 ts 类型错误的,但是有时候会需要根据一些参数来处理数组元素的内容,比如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
export type Config = {
type: "c" | "l" | "z";
name: string;
}[];

const flag = true;
const config: Config = [
...(flag
? [
{
type: "c",
name: "clz",
},
]
: []),
{
type: "c",
name: "czh",
},
];

原因则是使用扩展运算符那里,将{ type: "c", name: "clz"}识别成{ type: string, name: string }了。

这种情况下,可以使用as const来处理类似误差。

获取函数返回值类型

1
ReturnType<typeof setTimeout>;

适用场景:要使用的函数,并没有把返回值类型export出来,并且需要保存返回值(通过useRef保存的时候,就需要得到返回值的类型)

例子(随便声明一个函数):

1
2
3
4
5
6
7
8
9
10
11
12
enum CustomDate {
Month = "month",
Week = "week",
}

export function getCustomDate(a: number, b: number): CustomDate {
if (a + b > 10) {
return CustomDate.Month;
}

return CustomDate.Week;
}


没有办法定义类型的话,就会像上面一样报错。

使用ReturnType就可以解决这个问题。

1
2
const customDate = useRef<ReturnType<typeof getCustomDate>>();
customDate.current = getCustomDate(10, 20);

ts-node运行 ts 脚本

脚本需要类型,使用 ts 编写脚本的话,无法直接运行。可以通过安装ts来实现。

使用方法也非常简单,package.jsonscripts添加对应的命令,如execute: ts-node index.ts即可。也可以直接命令行npx ts-node index.ts

注意ts-node只能在commonJS中执行。不过可以还是可以直接在ts文件中使用importexport

这个issue中有提到。

项目开发中,可以添加-T参数:只转译,不做类型检查。类型检查可以通过vscode,以及提交前检查。

is 类型保护

联合类型可以通过公共属性进行类型保护。

如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
interface BaseUser {
name: string;
}

interface FreeUser extends BaseUser {
type: "free";
sayHello: () => void;
}

interface VIPUser extends BaseUser {
type: "vip";
sayHi: () => void;
}

export interface Props {
user: FreeUser | VIPUser;
}

export const handler = (props: Props) => {
const { user } = props;

if (user.type === "free") {
user.sayHello();
} else {
user.sayHi();
}
};

没有公共属性可以用于区分的时候,可以使用is类型保护。

1
2
3
const isVIPUser = (user: any): user is VIPUser => {
return user.sayHi !== undefined;
};

使用具体类型的属性、方法前,调用一下该方法即可。
如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
interface BaseUser {
name: string;
}

interface FreeUser extends BaseUser {
sayHello: () => void;
}

interface VIPUser extends BaseUser {
sayHi: () => void;
}

export interface Props {
user: FreeUser | VIPUser;
}

const isVIPUser = (user: any): user is VIPUser => {
return user.sayHi !== undefined;
};

export const handler = (props: Props) => {
const { user } = props;

if (!isVIPUser(user)) {
user.sayHello();
} else {
user.sayHi();
}
};

文章作者: 赤蓝紫
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 赤蓝紫 !
评论
  目录