对象
对象是包含一组键值对的实例,值可以是标量、函数、数组、对象等。对象类型的最简单声明方法,就是使用大括号表示对象,在大括号内部声明每个属性和方法的类型。
ts
const person: { name: string; age: number } = {
name: "rinvay",
age: 18,
};
type
和 interface
关键字也可以声明对象类型。
ts
type Person1 = {
name: string;
age: number;
};
interface Person2 {
name: string;
age: number;
}
const p1: Person1 = { name: "rinvay", age: 24 };
const p2: Person2 = { name: "rinvay", age: 24 };
可选属性
在属性后面加一个 ?
来表示该属性是可选的。
ts
type Person = {
name: string;
age?: number;
};
const p2: Person = { name: "树街猫" };
const p1: Person = { name: "rinvay", age: 24 };
只读属性
属性名前面加上 readonly 关键字,表示这个属性是只读的,不可修改。
ts
type Person = {
readonly name: string;
age?: number;
};
const p1: Person = { name: "rinvay", age: 24 };
p1.age = 2;
p1.name = "树街猫"; // error 无法为"name"赋值,因为它是只读属性
多个未知属性
通常外部 API 接口返回的对象,无法事前知道该对象会有多少属性,这时 ts 允许采用属性名表达式的写法来描述类型。
ts
type T = {
[s: string]: string | number;
};
const p1: T = { name: "rinvay", age: 24 };
解构赋值
解构赋值的类型写法,跟为对象声明类型是一样的。
ts
type T = {
x: string;
y?: number;
};
const p1: T = { x: "rinvay", y: 24 };
const { x, y }: T = p1;
接口 interface
interface 是对象的模板,是一系列方法的声明,需要由具体的类去实现。
ts
interface IPerson {
firstName: string
lastName: string
getName: () => string
}
const p1: IPerson = {
firstName: 'Tom',
lastName: 'Hanks',
getName: function () {
return `${this.firstName} ${this.lastName}`
},
}
在上面的例子中,定义了一个接口类型 Person
,它拥有三个属性 firstName
、lastName
和 getName
。任何实现这个接口的对象,都必须拥有与之对应类型的三个属性。p1
实现了接口 Person
的属性和方法。
interface 可以表示对象的各种语法。
ts
interface Rect {
x: number
y: number
z?: number // 可选参数
}
interface Person {
readonly name: string // 只读属性
age: number
}
// 定义接口参数
interface Params {
[name: string]: string | number
}
const data: Params = { name: 'rinvay', age: 18 }
interface IArray {
[index: number]: string
}
const words = ['A', 'B', 'C']
// 函数
interface F {
fn(x: number): number
}
interface F1 {
fn: (x: number) => number
}
// 函数重载
interface F2 {
fn(): number
fn(x: number): number
fn(x: number, y: number): number
}
继承
接口继承就是说接口可以通过其他接口来扩展自己,ts 允许接口继承多个接口。
继承 interface。
使用关键字 extends
,可以继承单接口和多个接口。
ts
interface Person {
age: number
}
// 单个接口继承
interface Musician extends Person {
instrument: string
}
interface ParentA {
v1: number
}
interface ParentB {
v2: number
}
// 多个接口继承
interface Child extends ParentA, ParentB {}
继承 type
interface
同样可以使用关键字 extends
继承 type
声明的对象类型
ts
type Person = {
age: number
}
interface Musician extends Person {
instrument: string
}
继承 class
interface
也可以继承 class
。
ts
class Shape {
area: number
}
interface A extends Shape {
getArea: () => number
}
const area: A = {
area: 100,
getArea: function () {
return this.area
},
}
上面示例中,A
继承了 Shape
,因此 A
有了Shape
的属性 area
和自己的属性getArea
。实现 A
接口的对象area
就需要实现这些属性。
interface 与 type 的区别
(1)type
能够表示非对象类型,而 interface
只能表示对象类型。
ts
type bizData = string | number | boolean
(2)interface
可以继承其他对象类型,type
不支持继承,只能通过 &
运算符来重新定一个类型。
ts
type Person = {
age: number
}
type Musician = Person & {
instrument: string
}
interface Musician extends Person {
instrument: string
}
(3)同名 interface
会自动合并,同名 type
则会报错。 interface
不允许与 type
同名。
ts
type Person = {
age: number
}
interface Person {
name: string // error 标识符"Person"重复。
}
(4)interface
不能包含属性映射([prop in keyof A]
表示依次得到类型 Point
的所有属性名,然后将每个属性的类型改成Point[Key]
,即为 number
。)。
ts
interface Point {
x: number;
y: number;
}
type Point1 = {
[Key in keyof Point]: Point[Key];
};
interface Point2 {
[Key in keyof Point]: Point[Key]; // error 应为声明或语句
};
(5)this
关键字只能用于 interface
。
ts
interface F {
add(num: number): this
}
type F = {
add(num: number): this // error "this" 类型仅在类或接口的非静态成员中可用。
}