1. 泛型
泛型的作用场景:当我们定义函数或类时,如果遇到类型不明确的就可以使用泛型,本质上来说就是参数的类型化。
参数的类型化:在定义这个函数时, 我不决定这些参数的类型,而是让调用者以参数的形式告知,我这里的函数参数应该是什么类型。(不定义为any的原因是会丢失类型信息)
function demo<T>(nbr: T): T {
return nbr
}
// 调用方式1: 明确传入类型
demo<number>(20)
demo<string>("你好")
//2.利用TS的类型推导 推出类型
demo(30)
demo("你好")
1.1 泛型的使用
//多类型传递
function demo<T, S, B>(nbr: T, str: S, bool: B) {
}
demo<number, string, boolean>(20, "你好", false)
1.2 泛型在接口的使用
interface Idemo<T = string, N = number> {
name: T
age: N
}
const demo: Idemo = {
name: "张三",
age: 12
}
1.3泛型在类中使用
class Demo<T>{
nbr: T
nbr2: T
constructor(x: T, y: T) {
this.nbr = x
this.nbr2 = y
}
fun() {
console.log(this.nbr)
}
}
const demo1 = new Demo(10, 20)
demo1.fun()
const demo2 = new Demo<number>(10, 30)
1.4 泛型约束
有时候我们希望传入的类型有某些共性,但是这些共性可能不是在同一种类型中:
比如string和array都是有length的,或者某些对象也是会有length属性的;
interface ILength {
length: number
}
function getLength<T extends ILength>(arg: T) {
return arg.length
}
getLength("abc")
getLength(["cba", "nba"])
getLength({length: 2})
2. 命名空间namespace
TS通过两种方式来声明作用域:
- 模块化:每一个文件就是一个模块 支持ES Module和CommonJS
- 命名空间:通过namespace来声明一个命名空间
命名空间也成为内部模块,是TS在ES6模块化出现前的方案。主要目的是将一个模块内部再进行作用域的划分,防止一些命名 冲突的问题。
//相同的方法名
export namespace demo1 {
export function demo(nbr: number, nbr2: number) {
return nbr + nbr2
}
}
export namespace demo2 {
export function demo(str: string, str2: number) {
return str + "的答案是:" + str2
}
}
3. TS类型查找
.d.ts文件:它是用来做类型的声明(declare)。 它仅仅用来做类型检测,告知typescript我们有哪些类型
TS通常会在三个场景中查找类型声明:
- 内置类型声明 ts包安装时自带的。比如
BOM API
,DOM API
等等。 - 外部定义的类型声明:通常引用库时,库自带的。例如
axios
。 - 自己定义类型声明。
本章主要讲自定义类型声明:
9.1 自定义类型声明
[