扩展
?:可选参数
可选链事实上并不是TypeScript独有的特性,它是ES11(ES2020)中增加的特性
- 可选链使用可选链操作符 ?
- 作用是当对象的属性不存在时,会短路,直接返回undefined,如果存在,那么才会继续执行
- 虽然可选链操作是ECMAScript提出的特性,但是和TypeScript一起使用更版本
type Person = {
name: string,
friend?: {
name: string,
age?: number
}
}
const info: Person = {
name: 'zs'
}
console.log(info.friend?.name);
??类似于||
??类似于||,都是或者的意思,但是??前面如果是undefined
或是null
才会运行后面的代码
console.log(null || 5); // 5
console.log(null ?? 5); // 5
console.log(undefined || 5); // 5
console.log(undefined ?? 5); // 5
console.log(0 || 5); // 5
console.log(0 ?? 5); // 0
在赋值时,可能会做判断没有值则赋值其他值,可以考虑使用??
或者使用||
let b = 0;
let a = b ?? 5;
console.log('a', a);
?.
当你访问对象里面的属性时,这个属性可能不存在,那么你访问时可能报语法错误。
?.
指当前面的值存在就访问后面的,如果不存在则返回undefined。
interface User {
name?: string;
age?: number;
getName?(): string;
user?: User
}
let obj: User = {
name: 'zs',
age: 20,
getName() {
return ''
},
user: {
name: '李四',
age: 30,
getName() {
return ''
},
}
}
let name = obj.user?.name;
obj.user?.getName?.();
非空断言(!.)
代表一定有值,意思是断言,告诉ts这个对象中一定有这个值。
interface User {
name?: string;
age?: number;
getName?(): string;
user?: User
}
let obj: User = {
name: 'zs',
age: 20,
getName() {
return ''
},
user: {
name: '李四',
age: 30,
getName() {
return ''
},
}
}
let name2: string = obj.user!.name!;
type
类型别名,顾名思义,给类型取一个别名
type Str = string;
let str: Str = '12';
type User = {
name?: string;
age?: number;
getName?(): string;
user?: User
}
let obj: User = {
name: 'zs',
age: 20,
getName() {
return ''
},
user: {
name: '李四',
age: 30,
getName() {
return ''
},
}
}
type和interface区别?
- interface可以被类实现,type只是类型别名,不能被类实现。
- 写法不一样,type使用
=
写类型。
?? 和 !!
有时候我们还会看到 !! 和 ?? 操作符,这些都是做什么的呢?
!!操作符:
- 将一个其他类型转换成boolean类型
- 类似于Boolean(变量)的方式
??操作符:
- 是ES11增加的新特性
- 空值合并操作符(??)是一个逻辑操作符,当操作符的左侧是 null 或者 undefined 时,返回其右侧操作数,否则返回左侧操作数
模块化
TypeScript支持两种方式来控制我们的作用域:
- 模块化:每个文件可以是一个独立的模块,支持ES Module,也支持CommonJS
- 命名空间:通过namespace来声明一个命名空间
模块化:
命名空间:
命名空间在TypeScript早期时,称之为内部模块,主要目的是将一个模块内部再进行作用域的划分,防止一些命名冲突的问题
类型查找
内置类型声明:
内置类型声明是typescript自带的、帮助我们内置了JavaScript运行时的一些标准化API的声明文件
- 包括比如Math、Date等内置类型,也包括DOM API,比如Window、Document等
内置类型声明通常在我们安装typescript的环境中会带有的
- https://github.com/microsoft/TypeScript/tree/main/lib
外部定义类型声明和自定义声明:
外部类型声明通常是我们使用一些库(比如第三方库)时,需要的一些类型声明
这些库通常有两种类型声明方式:
方式一:在自己库中进行类型声明(编写.d.ts文件),比如axios
方式二:通过社区的一个公有库DefinitelyTyped存放类型声明文件
该库的GitHub地址:https://github.com/DefinitelyTyped/DefinitelyTyped/
该库查找声明安装方式的地址:TypeScript: Search for typed packages
比如我们安装react的类型声明: npm i @types/react --save-dev
什么情况下需要自己来定义声明文件呢?
情况一:我们使用的第三方库是一个纯的JavaScript库,没有对应的声明文件;比如lodash
npm i lodash
src/types/lwj.d.ts
declare module "lodash" {
export function join(...args: any[]):any
}
xxx.ts
import _ from 'lodash'
_.join(['abc', 'cba'])
情况二:我们给自己的代码中声明一些类型,方便在其他地方直接进行使用;
type IDType = number | string
let id: IDType = 5
声明变量-函数-类
声明模块
我们也可以声明模块,比如lodash模块默认不能使用的情况,可以自己来声明这个模块:
声明模块的语法: declare module '模块名' {}。
- 在声明模块的内部,我们可以通过 export 导出对应库的类、函数等
declare文件
在某些情况下,我们也可以声明文件:
- 比如在开发vue的过程中,默认是不识别我们的.vue文件的,那么我们就需要对其进行文件的声明
- 比如在开发中我们使用了 jpg 这类图片文件,默认typescript也是不支持的,也需要对其进行声明
declare命名空间
比如我们在index.html中直接引入了jQuery:
tsconfig.json文件
tsconfig.json是用于配置TypeScript编译时的配置选项:
TypeScript: TSConfig Reference - Docs on every TSConfig option