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;
}
12. 总结
12.1 接口(interface)
- 定义:接口是一种数据类型,用于定义对象的结构,包括属性和方法。
- 重名合并:相同名称的接口会自动合并。
- 继承:接口可以继承父接口,拥有其所有属性和方法。
- readonly 修饰符:属性标记为
readonly
后,只能在对象创建时赋值。 - 可选属性:使用
?
操作符标记属性为可选。 - 索引类型:定义对象中元素的类型。
- 任意属性:对象可以有任意数量的属性,其类型为
any
,但确定属性和可选属性的类型必须是其类型的子集。 - 函数类型:用于描述对象的方法。
12.2 数组类型
- 类型[]:如
number[]
表示数组元素类型为number
。 - Array<类型>:如
Array<number>
与number[]
等同。 - 元组类型:固定长度和类型的数组。
- 接口表示数组:通过接口定义数组元素的类型。
- 多维数组:数组元素也是数组。
12.3 函数的 arguments
类数组
介绍 arguments
类数组的使用,以及 IArguments
接口的实现。