这是我参与「第五届青训营 」笔记创作活动的第8天
一、本堂课重点内容:
- 联合交叉类型
- 类型保护与类型守卫
- Merge 函数类型实现
- 函数返回值类型
- TypeScript 工程应用
二、详细知识点介绍:
TypeScript进阶语法
- 联合/交叉类型: TypeScript支持联合类型和交叉类型,联合类型是使用
|
运算符将多个类型组合在一起,而交叉类型是使用&
运算符将多个类型组合在一起。
type A = {a: number}
type B = {b: string}
let AB: A | B = {a: 1}
let AandB: A & B = {a: 1, b: 'string'}
-
类型保护与类型守卫: TypeScript支持类型保护和类型守卫,类型保护是指在运行时使用特定的逻辑来确定变量的类型,而类型守卫是指在编译时使用特定的逻辑来确定变量的类型。
function isFish(pet: Fish | Dog): pet is Fish { return (pet as Fish).swim !== undefined; } if (isFish(pet)) { pet.swim(); } else { pet.bark(); }
这段 TypeScript 代码定义了一个名为 isFish 的函数,它接收一个参数 pet,它的类型为 Fish 或 Dog 中的一种。
函数 isFish 定义了一个类型保护,使用了 TypeScript 的 "类型断言" 语法来判断 pet 参数是否是 Fish 类型。如果参数 pet 有 swim 属性,就说明它是 Fish 类型,返回 true。否则返回 false。
在 if 语句中,通过调用 isFish 函数来判断 pet 的类型,如果是 Fish 类型,则调用 pet.swim() 方法,如果是 Dog 类型,则调用 pet.bark() 方法。
-
高级类型: TypeScript支持一些高级类型,如索引类型、条件类型、自定义运算符类型等。
- 索引类型: TypeScript 支持使用
keyof
和索引类型查询类型,可以获取对象属性名的类型
interface Person {
name: string;
age: number;
}
type PersonKey = keyof Person; // "name" | "age"
-
条件类型: TypeScript 支持条件类型,可以根据条件判断类型
type TypeName<T> = T extends string ? "string" : T extends number ? "number" : T extends boolean ? "boolean" : T extends undefined ? "undefined" : T extends Function ? "function" : "object";
这段 TypeScript 代码定义了一个名为 TypeName 的泛型类型别名。它接收一个类型参数 T,并通过条件类型运算符 (T extends X ? Y : Z) 来判断 T 的类型。
当 T 是 string 类型时,TypeName 的类型为 "string"。当 T 是 number 类型时,TypeName 的类型为 "number"。同理,当 T 是 boolean、undefined、Function 时,TypeName 的类型分别为 "boolean"、"undefined"、"function"。如果 T 不是上述类型之一,那么 TypeName 的类型为 "object"。
这个类型别名可以用来在程序中获取变量的类型名称,或者在类型之间进行类型比较。例如,可以使用 TypeName 来判断一个变量是否是字符串类型。
-
自定义运算符类型: TypeScript 支持自定义运算符类型,可以使用自定义运算符类型来描述类型
type Nullable<T> = T | null;
type NotNullable<T> = T extends null ? never : T;
4.函数返回值类型:
TypeScript 支持使用 never
类型来表示函数永远不会返回值,可以使用never
类型来描述函数返回值类型
function throwError(message: string): never {
throw new Error(message);
}
"=>"
是 TypeScript 中用来定义函数类型的箭头符号。它可以被用来定义函数的参数类型和返回值类型。
举个例子:
let add: (x: number, y: number) => number = function(x: number, y: number): number {
return x + y;
}
上面的代码中,我们使用 "=>" 来定义了一个 add 函数,它接受两个 number 类型的参数 x 和 y,并返回一个 number 类型的结果。
在 TypeScript 中,这种类型的函数被称为箭头函数。
其实还有另一种简写的写法
let add = (x: number, y: number) => x + y
在上面的代码中,我们可以看到,函数体只有一条语句,并且是一个返回值,所以可以这样简写。
总之, "=>" 可以用来简洁地定义函数的类型,并且更易于阅读和理解。
TypeScript工程应用
相关loader:
在 NodeJs 应用中,TypeScript需要使用 TSC (TypeScript Compiler) 编译成 JavaScript。 TSC 是 TypeScript 的命令行工具,可以将 TypeScript 编译成 JavaScript。 命令行使用:
tsc --outDir dist --rootDir src src/index.ts
在工程应用中,使用 TypeScript 需要先安装 TypeScript 依赖包和配置 TypeScript 配置文件 (tsconfig.json)。配置文件中可以设置编译选项、文件路径等。
三、实践练习例子:
?
的意义: 在 TypeScript 中,?
表示可选属性。
interface SquareConfig {
color?: string;
width?: number;
}
let obj: SquareConfig = {};
obj.color = 'red';
这段代码定义了一个接口 SquareConfig,它包含了两个可选属性 color 和 width。
接着定义了一个变量 obj,它的类型是 SquareConfig。然后赋值为一个空对象{}。
最后,在obj对象上添加了一个color属性,并赋值为'red'。
这段代码简单的演示了如何使用接口来定义对象的类型。接口 SquareConfig 定义了对象应该具有的属性,并且这些属性都是可选的。通过定义 obj 的类型为 SquareConfig,我们可以确保 obj 对象只具有 SquareConfig 接口中定义的属性。
extends
/infer
的注意事项
四、课后个人总结:
学习 TypeScript
过程中,我发现联合类型和交叉类型是最难理解的部分。虽然它们是非常有用的特性,但是理解起来有些困难。我也发现,当我尝试在代码中使用它们时,很容易将它们与其他类型混淆。类型保护和类型守卫是我学习的另一个难点。它们是实现类型转换的关键,但是它们的实现方式有点复杂。我认为,这部分内容需要更多的练习和实践才能更好地理解。在函数类型实现中,我发现了 Merge
函数的用法。它是一个非常有用的函数,能够帮助我们合并两个对象的属性,但是我认为它的用法有些复杂,需要更多的练习才能熟练掌握。在函数返回值类型中,我学习了如何使用 "=>"
来定义函数的返回值类型。这是一个非常有用的特性,能够帮助我们更好地管理函数的返回值。在实例部分,我们练习了如何使用 "?" 来定义可选属性和使用 "extends" 和 "infer" 来实现泛型和类型推断。我发现,这些特性能够帮助我们更好地管理类型和提高代码的可读性。
总的来说,学习 TypeScript 是一个非常有益的经历。它是一种非常强大的语言,能够帮助我们更好地编写和管理代码。