接口补充、泛型、工具类型、空安全、模块化
一、接口补充
1.1、接口继承
作用:定义一个接口继承一个接口
基础代码:
interface 接口1{ 属性1:类型 }
interface 接口2 extends 接口1 { 属性2:类型 }
1.2、接口实现
作用:可以通过接口结合 implements 来限制 类 必须要有某些属性和方法
语法:class 类 implements 接口{}
代码演示:
//定义接口
interface Idog{
name:string
bark():void
}
//定义类实现接口
class dog implements Idog{
name:string = '金毛'
age:number = 2
bark() {
console.log('狂叫')
}
}
let Dog:dog = new dog()
console.log(Dog.name)
二、泛型
作用:泛型在保证类型安全(不丢失类型信息)的同时,可以让函数等与多种不同的类型一起工作,灵活可复用 通俗一点就是: 类型是可变的!
2.1、泛型函数
作用:就是泛型和函数结合到一起使用。
语法:function 函数名<>(形参:Type){}
代码演示:
function getDate<T>(args:T){
return [args]
}
getDate<string>('1')
getDate<number>(1)
getDate<boolean>(true)
getDate<number[]>([1,2,3,4,5,6])
2.2、泛型约束
作用:如果开发中不希望任意的类型都可以传递给 类型参数 , 就可以通过泛型约束来完成
语法:function 函数<Type extends 约束的类型>(){}
代码演示:
//枚举约束
function getcolor<T extends Color>(color:T){
return color
}
getcolor<Color>(Color.White)
//联合类型约束
function strboo<T extends string | boolean>(args: T){
return args
}
strboo<boolean>(true)
//接口类型约束
interface s{
name:string
}
function S<T extends s>(args:T){
return args
}
S<s>({name:'s'})
2.2.3、多个泛型约束
作用:日常开发的时候,如果有需要可以添加多个 类型变量,只需要定义并使用 多个类型变量即可
代码演示:
function funab<T1 extends number, T2 extends string>(a: T1, b: T2) {
console.log('', a, b)
}
funab<number, string>(1, '2')
2.2.4、泛型接口
概念:定义接口时结合泛型,那么这个接口就是 泛型接口
语法:interface 接口<>{ // 内部使用Type }
代码演示:
interface i<T>{
msg:string
cod:number
data:T
}
let Data :i<number[]>={
msg:'ok',
cod:200,
data:[1,2,3,4,5,6,7]
}
console.log(JSON.stringify(Data))
2.2.5、泛型类
概念:和泛型接口类似,如果定义类的时候结合泛型,那么这个类就是 泛型类
语法:class 类名<>{ // 内部可以使用 Type }
代码演示:
class Person <T> {
id: T
constructor(id: T) {
this.id = id
}
getId() {
return this.id
}
}
// 使用
let p = new Person<number>(10)
class Person <T> {
id: T
constructor(id: T) {
this.id = id
}
getId() {
return this.id
}
// 使用
let p = new Person<number>(10)
三、工具类型
3.1、Partial
作用:将Type的所有属性设置为可选
语法:
type 新类型 = Partial<接口>
type 新类型 = Partial<类>
代码演示:
//Partial<Type>将Type的所有属性设置为可选
interface Person{
name:string
age:number
}
type newperson = Partial<Person>
let n:newperson = {}
3.2、Required
作用:将 Type 的所有属性设置为必填
语法:
type 新类型 = Required<接口>
type 新类型 = Required<类>
代码演示:
//Required<Type>将 Type 的所有属性设置为必填
interface Iperson{
name?:string
}
type nIperson = Required<Iperson>
let newIperson:nIperson = {name:'小明'}
3.3、Readonly
作用:构造一个【新类型】,并将Type 的所有属性设置为readonly
语法:
type 新类型 = Readonly<接口>
type 新类型 = Readonly<类>
代码演示:
//Readonly<Type>构造一个【新类型】,并将Type 的所有属性设置为readonly
interface PERson{
name:string
}
type per = Readonly<PERson>
let p:per = {name:'小明'}
p.name
3.4、Record
作用:构造一个对象类型,其属性键为Keys,属性值为Type。该实用程序可用于将一种类型的属性映射到另一种类型。
代码演示:
//Record<Keys,Type>
let person2:Record<string,string> ={'name':'张三'}
let age:Record<string,number> = {'age':18}
四、空安全
4.1、 联合类型设置为空
代码演示:
// 通过联合类型设置为空
let x: number | null = null
x = 1
x = null
4.2、 非空断言运算符
作用:后缀运算符! 可用于断言其操作数为非空。
代码演示:
let x: number | null
let y: number
y = x + 1; // 编译时错误:无法对可空值作加法
y = x! + 1; // 通过非空断言,告诉编译器 x不为 null
4.3、 空值合并运算符
作用:用于检查左侧表达式的求值是否等于null。如果是,则表达式的结果为右侧表达式;否则,结果为左侧表达式。
代码演示:
class Person {
name: string | null = null
getName(): string {
// return this.name != null ? this.name : ''
// 等同于 如果 name不为空 就返回 name 反之返回 ''
return this.name ?? ''
}
}
4.4、可选链
作用:在访问对象属性时,如果该属性是undefined或者null,可选链运算符会返回undefined。
代码演示:
interface person1{
name:string
dogage?:number
}
let pers:person1 = {name:'小明'}
console.log(pers.dogage?.toString())
五、模块化
概念:把一个大的程序拆分成互相依赖的若干小文件,这些小文件还可以通过特定的语法组合到一起 这个过程称之为模块化。
5.1、默认导出和导入
代码演示:
// 默认导出
export default 需要导出的内容
// 默认导入
import xxx from '模块路径'
5.2、按需导入和导出(1)
按需导出代码演示:
export let name1 = '齐天大圣'
export const PI = Math.PI
function sayHi(){ console.log('我是齐天大圣孙悟空') }
interface iPerson {
name:string
}
class tools {
static getRandom(num: number) {
return Math.floor(Math.random() * num)
}
}
按需导入:
import {name1,PI} from '../tools/tools'
console.log(name1,PI)
按需导入和导出(1)
按需导出代码演示:
let name1 = '齐天大圣'
const PI = Math.PI
function sayHi(){ console.log('我是齐天大圣孙悟空') }
interface iPerson {
name:string
}
class tools {
static getRandom(num: number) {
return Math.floor(Math.random() * num)
}
}
export {name1,sayHi,iPerson,tools}
按需导入:
import {name1,iPerson,sayHi,tools} from '../tools/tools'
5.3、全部导入
代码演示: 导出部分不需要调整,调整导入的语法即可
// 一次性全部导入
import * as utils from '../utils/tools'
let person:utils.iPerson = {name:'孙悟空'}
console.log(utils.name1,utils.PI,person,utils.tools.getRandom(100))