持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第3天,点击查看活动详情
1. 引言
首先,我们来了解下TypeScript中的类型操作符有哪些?
- keyof 类型操作符:获取对象类型的键,(类型对比js 的Object.keys).
- typeof 类型操作符: 引用某个变量或者属性的类型(类型对比JavaScript 的typeof 操作符).
- 可选属性访问:可选访问操作符 ?.只检查它左边的值是null还是unfined——而不检查任何后续属性.
- ??操作符:在处理null或undefined时,作为一种回退到默认值的方法.
- ! 非空断言操作符:断言操作对象是非 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
}