改进 Typescript 的 7 个技巧
要掌握 TS 技能,你需要深入研究类型,并探索其所有可能性。本文专门讨论类型。
因此,为了提高您的技能并研究类型的功能如何改善开发,我强烈建议至少熟悉:
- 泛型
- 模板字面量
- 索引访问类型
- 实用程序类型
- KeyOf/TypeOf 运算符
- 条件类型
- 映射类型
学习时将针对每个案例使用当前示例:
type Todo = {
text: string,
type: "very urgent" |"urgent" | "not urgent",
daysToFinish: number,
isFinished: boolean
}
- 请注意,本文提供的信息并非完整,并非有意为之,且仅描述了最常用的用例。您可以在 TS 官方网站上找到涵盖该主题 100% 内容的完整信息。
现在让我们开始吧……
泛型
泛型的主要目的是提供可重用性。
让我们通过待办事项示例来学习。
type Todo = {
text: string,
type: "very urgent" |"urgent" | "not urgent",
daysToFinish: number,
isFinished: boolean
}
这里没有使用泛型,每个属性都有自己定义的类型。
泛型的实现如下:
type FirstTodo<T> = {
text: T,
type: "very urgent" |"urgent" | "not urgent",
daysToFinish: number,
isFinished: boolean
}
T 是什么意思?
三角括号中给出的 T 定义类型和文本具有相同的 T 类型。
例如,我们想为文本属性提供一个类型字符串(这是合乎逻辑的),并且我们对 TS 没有任何问题。
const firstTodo: FirstTodo<string> = {
text: "first todo",
type: "urgent",
daysToFinish: 6,
isFinished: false
}
现在让我们为每个属性添加泛型:
type SecondTodo<S, T, N, B> = {
text: S,
type: T,
daysToFinish: N,
isFinished: B
}
type TypeOptions = "very urgent" |"urgent" | "not urgent"
const secondTodo: SecondTodo<string, TypeOptions, number, boolean> = {
text: "first todo",
type: "urgent",
daysToFinish: 6,
isFinished: false
}
这里我们也为每个属性设置了逻辑类型,例如,我们为 B 设置的不是布尔值,而是一个数字,这意味着“isFinished”应该等于该数字。同样,对于“T”,我们设置了他的自定义类型,可以将其更改为其他类型。
模板字面量
它的工作原理与 JS 非常相似,在这里我们创建一种特殊类型来收集所有紧急程度。
type UrgencyRate = "very " | "" | "not "
type ThirdTodo<T> = {
text: T,
type: `${UrgencyRate}urgent`,
daysToFinish: number,
isFinished: boolean
}
const thirdTodo: ThirdTodo<string> = {
text: "third todo",
type: "not urgent",
daysToFinish: 6,
isFinished: false
}
索引访问类型
通过索引访问,我们可以创建一个类型,通过将一个(或一些)属性名称放在方括号中,该类型可以访问另一种类型的属性类型。
type Todo = {
text: string,
type: "very urgent" |"urgent" | "not urgent",
daysToFinish: number,
isFinished: boolean
}
type TodoText = Todo["text"] // string
type TodoTextAndIsFinished = Todo["text" | "isFinished"] // string | boolean
使用keyOf 运算符获取 1 个元素的所有属性类型。
type AllTypes = Todo[keyof Todo] // string | number | boolean
使用typeOf 运算符我们可以获取类型。
typeof "todo" // console.log -> string
它是如何根据当前元素创建新类型的方法。
const forthTodo: Todo = {
text: "forth todo",
type: "not urgent",
daysToFinish: 6,
isFinished: false
}
type AllTodoTypes = typeof forthTodo
// type AllTodoTypes = {
// text: string;
// type: "very urgent" | "urgent" | "not urgent";
// daysToFinish: number;
// isFinished: boolean;
}
实用程序类型
我们将仅观察 6 种实用程序类型,它们是 Required、Readonly、Partial、Record、Pick、Omit 和 NonNullable。
只读不允许从外部更改对象。
type Todo = {
text: string,
type: "very urgent" |"urgent" | "not urgent",
daysToFinish: number,
isFinished: boolean
}
const fifthTodo: Readonly<Todo> = {
text: "fifth todo",
type: "not urgent",
daysToFinish: 6,
isFinished: false
}
fifthTodo.text = "new text" // Cannot assign to 'text' because it is a read-only property.
必需和部分(必需 vs 部分)
Required 和 Partial 定义该类型的所有属性是否都是必需的。
type Todo = {
text: string,
type: "very urgent" |"urgent" | "not urgent",
daysToFinish: number,
isFinished: boolean
}
const todoWithRequired: Required<Todo> = {
text: "todo",
type: "very urgent",
daysToFinish: 10,
isFinished: true
}
const todoWithPartial: Partial<Todo> = {
text: "todo",
type: "very urgent"
}
记录(Record)是一个构造函数,它有助于创建一个新类型作为属性和类型的对象。
type TodosText = "first todo" | "second todo"
type TodoDescription = {
type: "very urgent" |"urgent" | "not urgent",
daysToFinish: number,
isFinished: boolean
}
const todos: Record<TodosText, TodoDescription> = {
"first todo": {
type: "not urgent",
daysToFinish: 10,
isFinished: false
},
"second todo": {
type: "urgent",
daysToFinish: 0,
isFinished: false
}
}
选择和省略(Pick vs Omit)
它们通过选择/或省略属性来帮助创建新类型。
type Todo = {
text: string,
type: "very urgent" |"urgent" | "not urgent",
daysToFinish: number,
isFinished: boolean
}
type todoWithPick = Pick<Todo, "text" | "isFinished">
const todoPick: todoWithPick = {
text: "todo",
isFinished: true
}
type todoWithOmit = Omit<Todo, "isFinished">
const todoOmit: todoWithOmit = {
text: "todo",
type: "not urgent",
daysToFinish: 40
}
NonNullable通过从初始类型中排除 undefined 和 null 来创建新类型:
type PossibleNullishTodo = {
text: string,
type: "very urgent" |"urgent" | "not urgent",
daysToFinish: number,
isFinished: boolean
} | null | undefined
type NotNullishTodo = NonNullable<PossibleNullishTodo>
// type NotNullishTodo = {
// text: string;
// type: "very urgent" | "urgent" | "not urgent";
// daysToFinish: number;
// isFinished: boolean;
}
条件类型
条件类型旨在定义类型之间的关系。
type Todo = {
text: string,
type: "very urgent" |"urgent" | "not urgent",
daysToFinish: number,
isFinished: boolean
}
interface UrgentTodo extends Todo {
type: "very urgent"
}
type ConditionalType = UrgentTodo extends Todo? true : false // true
映射类型
映射类型是在其他类型的基础上创建的,有助于避免重复代码。让我们为每个属性添加 readonly 和 ,并在映射时使其成为可选的。
type Todo = {
text: string,
type: "very urgent" |"urgent" | "not urgent",
daysToFinish: number,
isFinished: boolean
}
type customType<Type> = {
readonly [Property in keyof Type]?: Type[Property];
};
type ReadonlyPerson = customType<Todo>
//type ReadonlyPerson = {
//readonly text?: string | undefined;
//readonly type?: "very urgent" | "urgent" | "not urgent" | undefined;
//readonly daysToFinish?: number | undefined;
//readonly isFinished?: boolean | undefined;
}
这就是类型介绍的全部内容,希望您喜欢它:)
文章来源:https://dev.to/juliecherner/7-tips-to-improve-your-typescript-4o5o