该文章是 TypeScript 系列文章第三篇,该系列会带大家从基础开始学习直到在项目中使用。一周更新 2 篇左右,有任何问题留言提问,我都会一一解答。本篇文章介绍的是接口和泛型的知识。
接口
对于接口来说,你可以把它想成是 type
的加强版。也是用来声明对象类型的,但是用法更复杂。对于接口来说,他只存在于 TS 中,不会编译成 JS。
语法
interface Persons {
name: string
age: number
}
let p: Persons
这就是一个接口的最基语法,定义了对象里必须存在一个 key 为 name
且值为字符串。
但是有一点需要注意,如果你使用字面量的方式传入 Persons
类型的变量会有点不一样。
function say(p: Persons) {
console.log(p.name)
}
let p = { name: 'yck' }
say(p) // success
say({ name: 'yck' }) //error
你会发现在传入变量的编译通过了,但是传入字面量的时候编辑器就报错了,说必须传入 age
属性,这里你有几种办法可以解决。
第一种方式你可以使用类型断言 as
say({ name: 'yck' } as Person)
第二种方式你可以让属性可选 ?
// 问号表明这个属性可有可无
interface Persons {
name?: string
age?: number
}
第三种方式你可以使用可计算属性特性,这个和 ES6 的特性没什么区别
interface Persons {
name: string
age: number
// key 随便写
[key: string]: any
}
继承
对于接口来说,接口可以继承自接口也可以继承自类。接口也可以被类继承。
// 接口 Mine 中除了拥有 job 属性
// 同时也有了 Persons 中的属性
// 这个和类继承概念是一样的
interface Mine extends Persons {
job: string
}
class People {
job: string
}
// 和上面一样,也有了 People 中的属性
interface My extends People {
name: string
}
// 类如果继承了接口
// 那么在类中必须声明接口中的必选属性
class My extends People {
job: string
// name 必须声明
name: string
}
关于接口的知识就讲到这里。对于接口来说,用处就是用来定义对象类型的。
泛型
我们来考虑一个场景,我有一个需要参数的函数,但是我不知道参数会是类型,并且函数会讲这个参数返回出来。我拿到返回值还要进行一些操作。那么首先你肯定会考虑到使用 any
类型。这个答案肯定是没错的,但是首先在 TS 中我们应该尽量少的使用 any
类型,再者,我们后续还要对于返回值操作,但是这时候编辑器并不知道返回值的类型,所以他不能给我很好的一个代码提示。
function say(name: any) {
return name
}
say('yck').length
say(123).length
这时候泛型可以很好的帮助我们
// <>代表你使用了泛型,尖括号中的
// T 是自己随意命名的,在某些地方你
// 可以直接传入类型 Array<string>
// 并且在尖括号中如果想声明多个类型也是可以的
// <T, U>
// 声明好泛型后,你就可以像使用别的类型
// 一样使用他们
function say<T>(name: T) {
return name
}
// 当我们传入字符串的时候
// 代码会自动推断出返回值类型
// 也是字符串,也会有更精确的代码提示
say('yck').length
对于泛型来说,我们也可以规定他们的类型范围
// 这说明类型 T 必须是字符串或者数字
function say<T extends string | number>(age: T) {
return age
}
现在我们来将这讲的内容一起实践下
interface Type {
name: string
age: number
}
class Mine<T extends Type> {
obj: T
constructor(value: T) {
this.obj = value
}
}
// 你会发现这里在传参的时候
// 会直接给你 Key 的代码提示
let m = new Mine({name: 'yck', age: 25})
m.obj.age
所以对于泛型来说,第一个好处是让我们的代码能够更好的复用,更好的适用于各种类型。第二个好处就是增加了开发速度,原本需要手打的属性现在都有提示了。