TypeScript 技巧记录

const 的妙用

在日常开发中,经常能看到这种 const ROLE = {} as const

原来使用as const 主要是为了在 TypeScript 中将对象 ROLE 的属性设置为只读。从而增强安全性,此外还能帮助 TS 推到更精确的类型。

同时在使用的过程中使用 ROLE[”xxx”] as readonly 可以防止在代码中意外修改 ROLE 的值。

下面是一个权限判断的例子,可以有效的简化代码的逻辑。

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
30
export type User = { roles: Role[]; id: string };

type Role = keyof typeof ROLES;
type Permission = (typeof ROLES)[Role][number];

const ROLES = {
admin: [
"view:comments",
"create:comments",
"update:comments",
"delete:comments",
],
moderator: ["view:comments", "create:comments", "delete:comments"],
user: ["view:comments", "create:comments"],
} as const;

export function hasPermission(user: User, permission: Permission) {
return user.roles.some((role) =>
(ROLES[role] as readonly Permission[]).includes(permission)
);
}

// USAGE:
const user: User = { id: "1", roles: ["user"] };

// Can create a comment
hasPermission(user, "create:comments");

// Can view all comments
hasPermission(user, "view:comments");

never类型的妙用

  1. 代码限制
    never 类型限制,例如下面的代码中

    1
    2
    3
    4
    5
    6
    7
    8
    9
    type Method = "GET" | "POST"
    function myFetch(method:Method){
    if(method === "GET"){
    }else if(method === "POST"){
    } // 代码在这里没有什么问题,但是如果Method以后扩展了其他的类型会对逻辑产生问题,而不好察觉。
    else{
    const _n : never = method; // 这里表示不存在,如果扩展了其他类型,这里就会报错,容易排查问题
    }
    }
  2. 类型取反
    日常的typescript开发中你是否遇到这样的需求。对类型取反,例如出了number之外其他的类型都可以。那么可以使用三元表达式来完成。
    x:如果是这个类型?never:使用这个类型,对应的可以封装一下,采用泛型。

    1
    2
    3
    4
    function test<T>(x:T extends number ? never : T ){
    }
    // 可以弄成类型工具
    type BannerType<T,U> = T extends U ? never : T ;