typescript - is 关键字

6,398 阅读1分钟

前言

在写 ts 的时候,借助类型推导,我们可以不用费劲的为每个变量、函数定义类型,但类型推导也不是万能的,有时候并不能准确的进行类型的控制,所以我们需要自己指定类型,所以 is 关键字显得尤为重要。

正文

例 1

const getType = (val: unknown) => Object.prototype.toString.call(val).slice(8, -1).toLowerCase()

const isString = (val: unknown) => getType(val) === 'string'

可以看出如果 isString 返回了 true ,那么可以知道 val 是字符串,但编译器不知道,所以 val 依旧是 unknown ,也就不会有 toUpperCase 方法:

const foo = (val: unknown) => isString(val) ? val.toUpperCase() : val

如果不讲究的话可以用断言:

const foo = (val: unknown) => isString(val) ? (val as string).toUpperCase() : val

但上述断言是治标不治本的行为,我们可以通过 is 关键字更为精准的控制类型,以下代码相当于告诉编译器,如果返回结果为 true,则代表 val 是 string 类型:

const isString = (val: unknown): val is string => getType(val) === 'string'

例 2

可以借助泛型对复杂类型数据进行更深层次的类型控制

const getType = (val: unknown) => Object.prototype.toString.call(val).slice(8, -1).toLowerCase()

const isArray = <T>(val: unknown): val is T[] => getType(val) === 'array'
// 这里我们通过泛型说明如果 isArray 返回了 true ,意味着 val 是由 string 构成的数组
const foo = (val: unknown) => isArray<string>(val) ? val.map(item => item.toLowerCase()) : val

结语

以上内容如有不正之处,望各位指正!