5 种 Typescript 实用类型,让你的生活更轻松
对我们开发者来说,幸运的是,Typescript 内置了许多实用的类型。它们旨在提高代码的可读性,并在使用类型时减少样板代码。在今天的 Typescript 101 专栏中,我想谈谈 5 种我认为在日常开发中特别有用的实用类型。
目录
1. 省略
Omit<T, K>
根据官方文档,Constructs a type by picking all properties from T and then removing K.
换句话说,Omit
它是一个通用的实用程序类型,它会删除T
中指定的键K
。您可能需要此实用程序的用例之一是使用 DTO。如果您的项目使用严格的序列化,您可能会发现自己需要创建大量样板代码来描述不同的 DTO。让我们考虑一个示例,看看Omit
在这种情况下我们如何从中受益:
interface Post {
id: number;
title: string;
createdAt: string;
}
type CreatePostDto = Omit<Post, "id" | "createdAt">;
const createDto: CreatePostDto = {
title: "My post",
id: 1, // error
createdAt: "2020-06-06" // error
};
id
像或这样的属性createdAt
通常由后端设置,而您在通过 API 创建新实体时无法使用这些属性。您可以简单地通过在Post
界面中省略这些键来描述这种情况。
2. 选择
Pick
与 相反Omit
。Pick<T, K>
Constructs a type by picking the set of properties K from T.
继续使用 DTO 的相同示例,以下是如何定义 的类型UpdatePostDto
:
type UpdatePostDto = Pick<Post, "id" | "title">;
const updateDto: UpdatePostDto = {
id: 1,
title: "My new post",
createdAt: "2020-06-06" // error
};
Pick
和Omit
可以用来实现相同的目标,因为Pick<Post, "id" | "title">
和 相同Omit<Post, "createdAt">
。你始终可以决定使用哪个更短或更易读。
3. 部分
Partial<T>
是一种通用实用程序类型,它使所提供接口的所有属性都变为可选。我最喜欢的使用示例Partial
是通过合并来更新对象。在进行状态管理和状态更新时,它尤其常见。
interface AppState {
posts: Post[];
userName: string;
}
function updateState(state: AppState, update: Partial<AppState>): AppState {
return { ...state, ...update };
}
const initialState: AppState = {
posts: [],
userName: "Gleb"
};
const update: Partial<AppState> = {
userName: "John"
};
updateState(initialState, update);
Partial
将所有属性设置AppState
为可选,因此允许您仅定义更新的键,而不会丢失类型安全性。
4. 只读
Readonly<T>
是另一个方便的工具,在处理不可变数据时非常有用。如果你想强制执行不可变性,请尝试使用Readonly
:
const state: Readonly<AppState> = {
posts: [],
userName: "Gleb"
};
state.posts = []; // error: Cannot assign to 'posts' because it is a read-only property.
const updatedState: Readonly<AppState> = { ...state, posts: [] }; // ok
5.记录
我已经在这篇文章Record<T, K>
中讨论过了,但这个实用程序绝对值得再次提及。 在我的日常工作中,我需要处理很多数据网格。它们大多数都有一个非常相似的模式:它们将每一行定义为一个键值对映射。通常情况下,行接口的定义相当宽松:
type Cell = string;
interface Row {
[key: string]: Cell;
}
这意味着您可以根据需要添加任意数量的键。以下是代表单个帖子对象的行示例:
const post: Post = { id: 1, title: "My post", createdAt: "2020-06-06" };
const row: Row = {
title: post.title,
createdAt: post.createdAt,
randomKey: "is allowed"
};
幸运的是,有一个很好的方法来限制允许的键Record
:
type PostRow = Record<keyof Post, Cell>;
const postRow: PostRow = {
id: post.id.toString(),
title: post.title,
createdAt: post.createdAt,
randomKey: "is not allowed" // error
};
这种方法使行的预期类型对开发人员透明,并保持类型安全。只需稍加努力,您就可以创建可重用的通用行类型:
type PostRow<T> = Record<keyof T, Cell>;
const postRow: PostRow<Post> = {
id: post.id.toString(),
title: post.title,
createdAt: post.createdAt,
randomKey: "is not allowed" // error
};
概括
今天我们探索了 Typescript 实用类型的一些超能力,希望大家喜欢和我一起探索它们!我非常期待你们的反馈。如果你想学习一些关于 Typescript 或 Web 开发的具体知识,请留言,我们一起讨论。
如果您喜欢我的帖子,请传播并在 Twitter 上关注我🚀,以获取有关 Web 开发的更多精彩内容。
鏂囩珷鏉ユ簮锛�https://dev.to/glebirovich/5-typescript-utility-types-that-will-make-your-life-easier-i44