Typescript高级操作
tags: TypeScript Created time: December 24, 2022 8:42 PM emoji: https://www.typescriptlang.org/favicon-32x32.png?v=8944a05a8b601855de116c8a56d3b3ae
keyof
keyof操作符的作用是遍历一个对象/接口获取键值。
type Point = { x: number; y: number };
type P = keyof Point;
// 相当于
// type P = 'x' | 'y'
const p1:P = 123 // 报错
const p2:P = '888' // 报错
const p3:P = 'x' // 正确如果使用索引类型
type Point = { [name: string]: number };
type P = keyof Point;
// 相当于
// type P = numbertypeof
在js中typeof主要作用是判定变量类型,而ts扩展了typeof关键字的作用,使其可以进行“读取类型”操作。
这对于基本类型不是很有用,但与其他类型操作符结合使用,可以使用typeof方便地表示许多模式。例如,让我们从查看预定义的类型ReturnType开始。它接受函数类型并生成其返回类型:
为了避免混乱,ts限制typeof关键字后面只能跟标识符(变量名、函数名等)或对象属性。
索引访问类型(Indexed Access Types)
ts可以通过索引访问类型。可以通过type、interface或对象来设置类型。
甚至你还可以使用联合类型。
Mapped Types
有些时候你可能要重复定义某些类型,如果你不想编写重复的代码,可以使用映射类型。
这里使用到了泛型, [Property in keyof Type] 会迭代FeatureFlags 所有的key,你也可以让所有的key定义为原来的类型。
注意:在映射类型中不能定义属性和方法。
条件类型
很多时候我们需要根据输入值的类型来判断输出值的类型,这个时候就可以使用条件类型。
条件类型的写法有点类似于 JavaScript 中的条件表达式(condition ? trueExpression : falseExpression ):
例如:
条件类型配合泛型时就很有用了,例如我们需要实现一个函数,如果传入的参数是字符串则返回string,如果参数是数字类型则返回number,如果使用泛型+条件类型就可以这样写:
可以将条件类型提取出来:
infer
infer需要搭配条件类型来使用,**infer的作用是从正在比较的类型中推断类型,然后在 true 分支里引用该推断结果。**
我们用下面这个例子来描述infer的作用,在下面这个例子中,我们实现ArrayItemType类型来获取数组元素的类型,如果T是一个数组则返回其元素的类型,否则返回null,我们可以这样写:
这里运用了索引访问类型,如果使用infer,代码还能更简洁。
注意,infer推断的类型只能在条件类型的true分支中使用,不能在false分支使用,例如下面的代码:
类型谓词
TypeScript的类型谓词是一个检查类型的函数,用于检查一个输入值是否为某个特定类型。它的语法如下:
类型谓词的作用在于它能够检查一个值是否为某个特定类型,并且如果检查成功,返回true,否则返回false。它可以用于类型检查,以确保代码的正确性。
非空断言
Typescript还有个很实用的操作符——非空断言,它想到于告诉Typescript这个变量肯定不会是undefined或null。
它的用法是变量后面跟个!符号。
例如:
也可以用在对象的属性或方法上,就像可选链一样:
例如在vue的$refs中,有时我们明确知道ref引用了某个dom节点,例如this.$refs.linkRef,但是typescript会认为this.$refs.linkRef 有可能为undefined,这个时候就可以用非空断言,如this.$refs!.linkRef ,当然另一种写法是用可选链,因为在某些情况下(例如页面跳转)引用的dom节点确实会为空。
确定赋值断言
TypeScript 的确定赋值断言,允许在实例属性和变量声明后面放置一个 ! 号,从而告诉 TypeScript 该属性会被明确地赋值。
举个例子:
在这个例子中,我们已经知道变量a已经被赋值,但是typescript没有检测到,因此我们需要用确定赋值断言明确地告诉
实用类型
typescript提供一些全局范围可用的类型,可以简化我们的一些操作。
https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeys-type