1. // js:
  2. const getPersonName = person => {
  3. console.log(person.name);
  4. }
  5. const setPersonName = (person, name) => {
  6. person.name = name;
  7. }

我们这种js的语法其实是有一些问题的,如果传进来的person是一个undefined,那么语句执行的时候就会报错了。
我们为了避免错误:让person中一定要有name属性,可以使用类型注解:

  1. const getPersonName = (person: {name: string}) => {
  2. console.log(person.name);
  3. }
  4. const setPersonName = (person: {name: string}, name: string) => {
  5. person.name = name;
  6. }

这里我们发现有一些重复的数据定义,这个时候可以使用interface定义通用类型,定义一次即可:

  1. interface Person {
  2. name: string
  3. }
  4. const getPersonName = (person: Person) => {
  5. console.log(person.name);
  6. }
  7. const setPersonName = (person: Person, name: string) => {
  8. person.name = name;
  9. }

所以如果有通用的类型,我们就可以用interface表示出来。

type 和 interface,区别不大但是还是有区别的:
type可以直接代表一个基础类型,但是interface只能代码对象或者函数

  1. type Person = string; // type 是可以这样使用代表 string 的 但是interface 不能代表基础类型

在ts中我们一般能用接口 interface就用interface, 不行再考虑使用类型别名 type

如果我们把interface 做一些修改:

  1. interface Person {
  2. name: string,
  3. age: number
  4. }
  5. ....
  6. // 这里如果这样写代码就会报错了,因为接口要求我们传入age,但是我们没有传递。所以只能写入一个age
  7. const p1 = {
  8. name: 'cos'
  9. }
  10. getPersonName(p1);
  11. setPersonName(p1, 'rose');

但是存在一些情况下,我们有些时候,需要age, 有些时候不需要age,这时候,可以这样写:

  1. interface Person {
  2. name: string,
  3. age?: number // 表示这个age 是可有可无的。
  4. }

如果我们希望某个属性是只读的,可以使用readonly

  1. interface Person {
  2. readonly name: string,
  3. age?: number
  4. }

image.png

如果这样写,其实是不会报错的,

  1. interface Person {
  2. name: string,
  3. age?: number
  4. }
  5. ...
  6. const p1 = {
  7. name: 'cos',
  8. gender: 'male'
  9. }
  10. getPersonName(p1);
  11. ...

但是如果我们以一种字面量的形式传递参数是会报错的。比如:
image.pngimage.png
注意:当使用字面量的形式直接传递一个对象给变量的时候,TS会对类型进行强校验。

这样其实也是有问题的,比如,我的对象中具体有什么属性是不确定的,某个属性可能有、也可能没有。这样的话就会有问题了。我们可以这么写:

  1. interface Person {
  2. // readonly name: string,
  3. name: string,
  4. age?: number,
  5. [propsName: string]: any // 表示,这个属性,属性名是字符串,值可以是任意类型
  6. }
  7. // 这样多出其他属性也是ok的。
  8. const p1 = {
  9. name: 'cos',
  10. gender: 'male',
  11. job: 'web'
  12. }

接口中不仅可以存一些属性也可以存储一些方法。

  1. interface Person {
  2. // readonly name: string,
  3. name: string,
  4. age?: number,
  5. [propsName: string]: any,
  6. say(): string // 定义一个方法 say , 返回值为字符串
  7. }
  8. // 这时候其实就需要定义一个say 方法,并返回字符串。否则就会报错。
  9. const p1 = {
  10. name: 'cos',
  11. gender: 'male',
  12. job: 'web',
  13. say() {
  14. return 'say hi'
  15. }
  16. }
  17. getPersonName(p1);

一个类应用一个接口,那么这个类里面就必须具备这个接口中的属性, 否则这个类就会报错。

  1. interface Person {
  2. // readonly name: string,
  3. name: string,
  4. age?: number,
  5. [propsName: string]: any // 表示,这个属性,属性名是字符串,值可以是任意类型
  6. say(): string // 定义一个方法 say , 返回值为字符串
  7. }
  8. ...
  9. // 一个类应用一个接口,那么这个类里面就必须具备这个接口中的属性
  10. class User implements Person {
  11. name = 'rose';
  12. say() {
  13. return 'hi..';
  14. }
  15. }

接口互相之间也可以进行继承

  1. interface Person {
  2. // readonly name: string,
  3. name: string,
  4. age?: number,
  5. [propsName: string]: any,
  6. say(): string // 定义一个方法 say , 返回值为字符串
  7. }
  8. // 表示 Teacher 继承了 Person下面所有属性和方法,并且它还可以有自己的属性和方法
  9. interface Teacher extends Person {
  10. teach(): string
  11. }
  12. const setTech = (teacher: Teacher, name: string) => {
  13. console.log(person.name);
  14. }
  15. const obj = {
  16. name: 'cos',
  17. say() {
  18. return 'cos';
  19. },
  20. teach() { // 这个teach 必须存在否则会报错
  21. return 'teach'
  22. }
  23. }
  24. setTech(obj, 'cos')

接口除了可以定义属性和方法之外,自身还可以定义一个函数。

  1. // 这种语法的含义,表示我们在定义一个函数的类型声明,接口能够代表一个函数的类型
  2. // 这个函数必须接受一个string类型的参数,并且返回值也是string
  3. interface sayHi {
  4. (word: string): string
  5. }
  6. const say: SayHi = (word: string) => {
  7. return word;
  8. }

interface 也可以定义数组这些索引类型。
函数类型和索引类型用的不错。

总结:

interface 和 type 类似但不完全一致, interface 只能定义对象或者函数,type 可以定义基础类型
? // 表示 这个属性可有可无
readonly // 标识该属性只读
[propName: string]: any
say(): string // 定义一个函数,并返回字符串类型

接口可以继承:interface Teacher extends Person {} // 一定有老的东西,也可以有新的东西

接口也可以直接定义一种方法类型:
interface sayHi {
(word: string): string
}

接口其实就是我们在使用ts进行开发的过程中,给我们做语法提示的一个工具。
真正编译成js代码的时候,会把关于接口和类型的代码全部剔除掉。