02.TypeScript 接口和对象类型

146 阅读3分钟

02.TypeScript 接口和对象类型

1. interface 接口

接口(interface)是 TypeScript 的一种数据类型,它定义了对象的结构。接口可以用来定义对象的属性和方法。

interface Person {
  name: string;
  age: number;
}

const person: Person = {
  name: 'Alice',
  age: 25
};

注意:person 对象中的属性必须与 Person 接口中的属性完全一致。如果属性名不一致,或者属性类型不一致,就会报错。Person 接口是对 person 对象的约束,它定义了 person 对象的结构。

2. 重名接口(interface)的合并

如果两个相同的接口,TypeScript 会自动合并它们。

interface Person {
  name: string;
  age: number;
}

interface Person {
  address: string;
}

const person: Person = {
  name: 'Alice',
  age: 25,
  address: '123 Main St'
};

3. 接口(interface)继承

接口可以继承,继承的接口会自动拥有父接口的所有属性和方法。

interface Animal {
  name: string;
  sound: string;
}
interface Dog extends Animal {
  breed: string;
}
const myDog: Dog = {
  name: 'Rufus',
  sound: 'Woof',
  breed: 'Golden Retriever'
};

Dog 接口继承了 Animal 接口,因此 Dog 接口拥有 Animal 接口的所有属性和方法。

4. 接口(interface)的 readonly 修饰符

接口中的属性可以被标记为 readonly,表示该属性只能在对象刚刚创建时被赋值,之后不能被修改。

interface Person {
  readonly name: string;
  age: number;
}

const person: Person = {
  name: 'Alice',
  age: 25
};

// Error: Cannot assign to 'name' because it is a read-only property.
person.name = 'Bob';

5. 接口(interface)的可选属性(使用?操作符)

接口中的属性可以被标记为 ?,表示该属性可以不存在,也可以存在。

interface Person {
  name: string;
  age?: number;
}

const person: Person = {
  name: 'Alice'
};

6. 接口(interface)的索引类型

接口可以定义索引类型,用来描述对象中元素的类型。

interface StringArray {
  [index: number]: string;
}

const myArray: StringArray = ['hello', 'world'];

// 等同
const arr:string[] = ['hello', 'world'];

在上面的例子中,StringArray 接口定义了一个索引类型为 number 的属性。这意味着 myArray 数组的索引必须是数字,并且元素的类型必须是 string。

7. 接口(interface)的任意属性

接口可以定义任意属性,即不管对象中有没有这些属性,都可以正常访问。

interface Person {
  name: string;
  [propName: string]: any;
}

const person: Person = {
  name: 'Alice',
  age: 25,
  address: '123 Main St'
};

在上面的例子中,Person 接口定义了一个任意属性,即 Person 对象中可以有任意数量的属性,这些属性的类型为 any。

注意:一旦定义了任意属性,那么确定属性和可选属性的类型都必须是它的类型的子集。

8. 接口(interface)的函数类型

接口可以定义函数类型,用来描述对象的方法。

interface Person {
  name: string;
  sayHello(): void;
}

const person: Person = {
  name: 'Alice',
  sayHello() {
    console.log(`Hello, my name is ${this.name}`);
  }
};

person.sayHello(); // Output: Hello, my name is Alice

注意:

  • 接口中的函数类型只能是方法,不能是属性。
  • 接口中的函数类型可以有参数,也可以没有参数。

9. 数组类型

TypeScript 还可以定义数组类型,用来描述数组中元素的类型。

9.1 类型[]

let myArray: number[] = [1, 2, 3];

myArray.push('4'); // Error: Argument of type 'string' is not assignable to parameter of type 'number'.

myArray.push(4); // OK

9.2 Array<类型>

let myArray: Array<number> = [1, 2, 3];

myArray.push('4'); // Error: Argument of type'string' is not assignable to parameter of type 'number'.

myArray.push(4); // OK

9.3 元组类型

let myTuple: [string, number];
myTuple = ['hello', 25];

myTuple[0] = 123; // Error: Type '123' is not assignable to type'string'.

myTuple[1] = 'world'; // Error: Type '"world"' is not assignable to type 'number'.

9.4 接口(interface)表示数组

interface StringArray {
  [index: number]: string;
}

const myArray: StringArray = ['hello', 'world'];

myArray.push('!'); // Error: Property 'push' does not exist on type 'StringArray'.

9.5 多维数组

let arr: string[][] = [  ['hello', 'world'],
  ['foo', 'bar']
];
arr.push(['baz', 'qux']);

10. 函数的 arguments 类数组

function myFunction(...args: any):void {
  console.log(arguments);
  const arr: number[] = arguments; // Error: Type 'IArguments' is not assignable to type 'number[]'.
  const args: IArguments = arguments;
}

11. IArguments 接口的实现

interface IArguments {
  length: number;
  [index: number]: any;
}