高级使用
联合类型
表示一个值可以是几种类型之一,适合于那些值可以为不同类型的情况。我们用竖线( | )分隔每个类型,所以 number | string | boolean表示一个值可以是 number, string,或 boolean。当函数的入参或者某个变量,可以是多个不同类型时使用。但是需要注意的是,联合类型的值只能调用所有类型里共有的方法或属性。
1 | function padLeft(value: string, padding: string | number) { |
交叉类型
将多个类型合并为一个类型,使用 & 符号将多个类型组合在一起,表示结果的类型是所有列出类型的集合。
1 | type Student = { |
类型保护与区分类型
1 | interface Bird { |
联合类型适合于那些值可以为不同类型的情况。 但当我们想确切地了解是否为 Fish时怎么办?
方法1:
通常使用类型断言,确保这段代码不会报错
1 | let pet = getSmallPet(); |
方法2:
但是对于我们判断过的类型,在使用时还要再次判断,就感觉是冗余的麻烦的,所以我们会寻求更好的方法: 用户自定义的类型保护
我们想要的效果是,一次检查类型后续直接知道类型而不需要再检查,就要使用TypeScript里的类型保护机制
谓词为 parameterName is Type这种形式,parameterName必须是来自于当前函数签名里的一个参数名。
1 | function isFish(pet: Fish | Bird): pet is Fish { |
每当使用一些变量调用 isFish时,TypeScript会将变量缩减为那个具体的类型,只要这个类型与变量的原始类型是兼容的。
注意TypeScript不仅知道在 if分支里 pet是 Fish类型; 它还清楚在 else分支里,一定 不是 Fish类型,一定是 Bird类型。
1 | // 'swim' 和 'fly' 调用都没有问题了 |
typeof类型保护
1 | function isFish(pet: Fish | Bird): pet is Fish { |
不是必须要像上面一样,定义一个函数来判断类型是否是原始类型,也就是不必将 typeof x === “number”抽象成一个函数,因为TypeScript可以将它识别为一个类型保护
可以直接这样
1 | function padLeft(value: string, padding: string | number) { |
这些* typeof类型保护*只有两种形式能被识别: typeof v === “typename”和 typeof v !== “typename”, “typename”必须是 “number”, “string”, “boolean”或 “symbol”。 但是TypeScript并不会阻止你与其它字符串比较,语言不会把那些表达式识别为类型保护。
instanceof类型保护
instanceof类型保护是通过构造函数来细化类型的一种方式。
instanceof的右侧要求是一个构造函数,TypeScript将细化为:
1、此构造函数的 prototype属性的类型,如果它的类型不为 any的话
2、构造签名所返回的类型的联合
1 | // 类型为SpaceRepeatingPadder | StringPadder |
类型保护和类型断言
类型断言可以手动去除null。语法是添加 ! 后缀: identifier!从 identifier的类型里去除了 null和 undefined, 这对很多需要调用该变量类型的方法时很有用,起到了类型保护的容错作用、保证代码的健壮性,自己不用先判断该值是否存在再赋值调用了:
1 | function fixed(name: string | null): string { |
类型别名
类型别名会给一个类型起个新名字。 类型别名有时和接口很像,但是可以作用于原始值,联合类型,元组以及其它任何你需要手写的类型。起别名不会新建一个类型 - 它创建了一个新名字来引用那个类型。
1 | type Name = string; |
接口 vs. 类型别名
1.错误信息不会使用别名。
2.接口是创建一个新的类型,别名不会创建一个新类型,是对原有类型的引用。
3.即使使用别名,编辑器只能提示还是会显示原有类型名称。
索引类型
1 | function pluck<T, K extends keyof T>(o: T, names: K[]): T[K][] { |
这段代码中,keyof T, 索引类型查询操作符。**T[K], 索引访问操作符
对于任何类型 T, keyof T的结果为 T上已知的公共属性名的联合
let personProps: keyof Person; // 'name' | 'age'
使用 const enum 维护常量表
1 | // 使用 const enum 维护常量 |
typescript 工具函数
学习了这些属性,感觉自己对TypeScript有了入门的一些了解,其余暂未能学习了解到内容,就等着在工作中踩坑学习了。在工作中,引入TypeScript确实是很强大很方便的一个选择,方便我们维护代码的同时,极重要的增强了代码的健壮性,类似can not find property、没有这个方法等等的错误,编译时就能让你意识到去避免,使得线上的代码更可靠!