【Typescript 系列】第三节:操作符

144 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第3天,点击查看活动详情

1. 引言

首先,我们来了解下TypeScript中的类型操作符有哪些?

  1. keyof 类型操作符:获取对象类型的键,(类型对比js 的Object.keys).
  2. typeof 类型操作符: 引用某个变量或者属性的类型(类型对比JavaScript 的typeof 操作符).
  3. 可选属性访问:可选访问操作符 ?.只检查它左边的值是null还是unfined——而不检查任何后续属性.
  4. ??操作符:在处理null或undefined时,作为一种回退到默认值的方法.
  5. ! 非空断言操作符:断言操作对象是非 null 和非 undefined 类型的.

2. 含义

是TypeScript 操作类型的方式

3. 作用

获取对象类型,设置操作属性

4. 例子

1.keyof 类型操作符

例句一:

type User = {
  id: number,
  name: string
}
type UserKeys = keyof User // ===> 'id' || 'name'
type judge<T,U> = T extends U ? true : false
let a: judge<'id',UserKeys> // true
例句二:

type U1 = User['id'] // number
type U2 = User['id' | 'name'] // number | string
type U3 = User[keyof User] // number | string

例句三:

let user: User = {
  id: 123,
  name: '校长'
}
// js
function getPropertyJs(obj,key){
  return obj[key]
}
// ts
function getPropertyTs<T extends object,K extends keyof T>(obj: T,key: K){
  return obj[key]
}
const userId = getPropertyTs(user,'id') // number
const userName = getPropertyTs(user,'name') // string
const userAge = getPropertyTs(user,'age') // 报错

例句四:

type K1 = keyof any // string | number | symbol
type K2 = keyof never // string | number | symbol
type K3 = keyof unknown // never
type K4 = keyof boolean // 'valueOf'
type K5 = keyof string // number | typeof Symbol.iterator | "toString" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" | "search" | "slice" | ... 30 more 
type K6 = keyof number // "toString" | "toFixed" | "toExponential" | "toPrecision" | "valueOf" | "toLocaleString"

例句五:

class Person {
  id: number = 666;
  name: string = '阿宝哥';
}
type P = keyof Person // 'id' || 'name'

2.keyof + typeof 类型操作符
例句一:
enum HttpMethods {
  Get,
  Post
}
type MethodKey = keyof HttpMethods // "toString" | "toFixed" | "toExponential" | "toPrecision" | "valueOf" | "toLocaleString"
type Method = keyof typeof HttpMethods // 'Get' | 'Post'

例句二:
let s = "hello";
let n: typeof s; // let n: string

3.可选属性访问
let x = foo?.bar.baz(); 
// 等价于let x = foo === null || foo === undefined ? undefined : foo.bar.baz();
// 用于判断链式可选调用

4. ??操作符
let y = foo ?? bar();
// 说明foo值在“存在”时将被使用;但当它为null或undefined时,计算bar()代替它。

5. ! 非空断言操作符
function noUndefined (s: string | undefined) {
  const hi1 = s!.toLowerCase() // OK
  const hi2 = s.toLowerCase() // Error: Object is possibly 'undefined'
}
注意:非空断言操作符--> 这样写只是为了骗过编译器,防止编译的时候报错,但打包后的代码可能还是会报错

5. 总结

操作符对于类型检测系统来说就像“人体的手和脚”,是操作检测类型的工具

6. 互动

上一节的答案公布:

如果我有个目标接口类型为
interface Person  {
  name: string
  age:number
  sex: string
}
通过‘模板字面量方法’映射一个类型方法
type Getter<T> = {
  [P in keyof T as `get${Capitalize<P & string>}`]: () => T[P]
}
interface Person  {
  name: string
  age:number
  sex: string
}
type GetPerson = Getter<Person>
// 结果如下
type GetPerson = {
  getName: () => string
  getAge: () => number
  getSex: () => string
}