TypeScript--高级用法
1. 运算符
- 可选链运算符 ?.
判断左侧的表达式 是否是 null或者 undefined ,如果是,则会停止表达式的运行,减少我们大量的 && 运算
obj?.prop
obj?.[index]
func?.(args)
- 非空断言运算符 !
强调对应的元素不是null 和 undefined
function onClick(callBack?: () => void) {
callBack!()
}
let a: {foo?: string} = {foo: 'foo'}
let b = a!.foo
上面的列子中 callBack 和 foo 是可选, 在使用的时候 使用 !来告诉编译器 他是非空的
- 空值合并运算符 ??
?? 和 js 中 || 比较类似,区别在于 ?? 只有左侧表达式为 null 或者 undefined 才会返回 右侧表达式。 || 左侧表达式 为 0 false 等 都会返回右侧表达式
const type = option.type?? 'type1'
- 模板字面量类型
type word = 'word'
type helloword = `hello ${word}`
- 联合类型
type T1 = 'header' | 'footer'
type T2 = `${T1}_id` // header_id footer_id
- 内置字符操作类型
Uppercase 将小写 转为大写
Lowercase 将大写 转为小写
Capitalize 将第一个字符转为大写
Uncapitalize 将第一个字符转为小写
type Greeting = 'Hello word'
type ShoutGreeting = Uppercase<Greeting> // HELLO WORD
type QuiteGreeting = Lowercase<Greeting> // hello word
2. 类型守卫
是可执行运行时检查的一种表达式, 用于确保该类型在一定范围内,换句话就是 类型首位可以保证一个字符串是一个字符串,尽管他的值 也可能是个 数值
类型守卫的思想是 尝试检测属性,方法 或者原型,以确定如何处理值
typeof 关键字
function padLeft(value: string; padding: string | number) {
if (typeof padding === 'number') {
// 处理 number
}
if (typeof padding === 'string') {
// 处理 string
}
}
instanceof 关键字
判断一个对象是否是某个类的实例
in 关键字
使用的情况 和js 中的使用 是相同的
interface Admin {
name: string;
privi: string;
}
interface Empolee {
name: string;
startData: Date
}
type UnknowEmpolee = Admin | Empolee
function print (emp: UnknowEmpolee) {
if ('startData' in emp) {
console.log('.....')
}
}
使用switch case 来进行可辨识联合
interface One {
type: 'one';
num: 98;
}
interface Two {
type: 'two';
nums: 98;
}
interface Three {
type: 'three';
numss: 98;
}
let classNum = One | Two | Three;
function sum (option: classNum) {
switch (option.type) {
case: 'one':
return option.num * 9;
case: 'two':
return option.nums * 9
case: 'three':
return option.numss * 9
}
}
类型谓词 is
先看下没有用 is 这个谓词的时候的写法
function isBird(bild: Bird | Fish): boolean {
return !!(bird as Bird).fly
}
function isFish(fish: Bird | Fish): boolean {
return !!(fish as Fish).swim
}
function start(pet: Bird | Fish) {
if (isBird(pet)) {
(pet as Bird).fly()
}else if (isFish(pet)) {
(pet as Fish).swim()
}
}
这里是使用 is 这个谓词的写法
function isBird(bild: Bird | Fish): bird is Bird {
return !!(bird as Bird).fly
}
function start(pet: Bird | Fish) {
if (isBird(pet)) {
Bird.fly()
}else if (isFish(pet)) {
Fish.swim()
}
}
在这里定义 isBird 的返回值时, bird is Bird 也是一个 boolean 值, 但是多了一层含义就是 bird 就是 Bird 这个类型的值
这样在start 中我们使用的时候就不需要 写类型断言了
3. 声明合并
函数合并
function add (a: number, b: number): number
function add (a: string, b: string): string
function add (a: string, b: number): string
function add (a: number, b: string): string
function add (a: Combinable, b: Combinable) {
if (typeof a == 'string' || typeof b == 'string') {
return a.toString() + b.toString()
}
return a + b
}
重载时,一定要把最精确的定义放在最前面,因为编译时会查找重载列表,尝试使用第一个重载定义。
接口合并
interface Alarm {
price: number;
}
interface Alarm {
weight: number;
}
等价与
interface Alarm {
price: number;
weight: number;
}
这里需要注意的时, 接口合并的时候, 同一个属性的类型不能前后定义不一致
4. 申明文件 .d.ts
主流的库都是 js 编写的,不支持类型系统,这个时候需要编写包含类型注释的 .s.ts 文件, 便可以在使用js 库的时候,获得静态类型检查
全局变量的申明写法
declare var 声明全局变量
declare function 申明全局方法
declare class 申明全局类
declare enum 申明全局枚举
declare namespace 申明有子属性的全局对象
interface type 申明全局类型
全局模块 和本地模块
区分两种模块 就看文件中有没有 import export ,有这两个关键字就是本地模块,使用的时候需要导入
自动生成声明文件
在ts.config.json中 设置 declaration为 true 这样就会为你自动生成 申明文件
{
compilerOptions: {
declaration: true
}
}
Definitely Typed 这个项目中有写好的 申明文件, 用的时候,可以在这个项目中去下载