TypeScript 对象知识大全
编程小白也能理解的 TypeScript 对象详解
TypeScript 对象核心概念
对象是什么
多个属性的集合,包含键值对
类型定义
使用接口或类型别名定义对象结构
属性类型
必备、可选、只读三种属性
高级特性
索引签名、解构、展开等
一、对象的基本概念
对象是包含多个键值对(属性)的集合,就像现实生活中的”物体”有多个特征。
创建对象
// 创建简单对象
let person = {
name: “小明”,
age: 25,
isStudent: false
};
let person = {
name: “小明”,
age: 25,
isStudent: false
};
访问对象属性
// 点号表示法
console.log(person.name); // “小明”
// 方括号表示法
console.log(person[“age”]); // 25
console.log(person.name); // “小明”
// 方括号表示法
console.log(person[“age”]); // 25
提示: 使用点号表示法更简洁,方括号表示法在属性名是变量或包含特殊字符时很有用。
二、定义对象类型
使用接口(Interface)
接口就像创建对象的蓝图,定义了对象应该有哪些属性和这些属性的类型。
// 定义Person接口
interface Person {
name: string;
age: number;
isStudent?: boolean; // 可选属性
}
interface Person {
name: string;
age: number;
isStudent?: boolean; // 可选属性
}
使用类型别名(Type)
// 使用type定义对象类型
type PersonType = {
name: string;
age: number;
isStudent?: boolean;
};
type PersonType = {
name: string;
age: number;
isStudent?: boolean;
};
应用对象类型
// 使用Person接口
let user: Person = {
name: “小红”,
age: 30
// 没有isStudent也可以,因为它是可选的
};
let user: Person = {
name: “小红”,
age: 30
// 没有isStudent也可以,因为它是可选的
};
三、对象属性类型
1. 必备属性
对象必须包含这些属性,不然TypeScript会报错。
interface Car {
brand: string; // 必备属性
year: number; // 必备属性
}
brand: string; // 必备属性
year: number; // 必备属性
}
2. 可选属性
属性名后加?表示这个属性可有可无。
interface Car {
brand: string;
year: number;
color?: string; // 可选属性
}
brand: string;
year: number;
color?: string; // 可选属性
}
3. 只读属性
属性前加readonly,表示这个属性只能读取,不能修改。
interface Point {
readonly x: number;
readonly y: number;
}
let p: Point = { x: 10, y: 20 };
p.x = 5; // 错误!x是只读的
readonly x: number;
readonly y: number;
}
let p: Point = { x: 10, y: 20 };
p.x = 5; // 错误!x是只读的
四、对象高级特性
1. 索引签名
当你不确定对象会有哪些属性名,但知道属性值类型时使用。
// 可以添加任意字符串类型的属性名,值都是数字
interface NumberDictionary {
[key: string]: number;
}
let scores: NumberDictionary = {
math: 95,
english: 89
};
interface NumberDictionary {
[key: string]: number;
}
let scores: NumberDictionary = {
math: 95,
english: 89
};
2. 对象解构
从一个对象中提取属性并赋值给变量。
let person = { name: “小明”, age: 25 };
// 解构赋值
let { name, age } = person;
console.log(name); // “小明”
console.log(age); // 25
// 解构赋值
let { name, age } = person;
console.log(name); // “小明”
console.log(age); // 25
3. 对象展开
使用…语法复制或合并对象。
let first = { a: 1, b: 2 };
let second = { c: 3, d: 4 };
// 合并对象
let combined = { …first, …second };
// { a: 1, b: 2, c: 3, d: 4 }
let second = { c: 3, d: 4 };
// 合并对象
let combined = { …first, …second };
// { a: 1, b: 2, c: 3, d: 4 }
接口 vs 类型别名
两者都可以用来定义对象类型,但有些细微差别:
特性 | 接口 (Interface) | 类型别名 (Type) |
---|---|---|
扩展方式 | 使用 extends 关键字扩展 | 使用 & 符号交叉类型扩展 |
重复声明 | 会自动合并同名接口 | 不能重复声明 |
使用场景 | 主要定义对象形状 | 可定义任意类型(联合、元组等) |
示例 | interface User { name: string; } | type User = { name: string; } |
建议: 定义对象类型优先使用接口(Interface),需要定义联合类型、元组等复杂类型时使用类型别名(Type)。
五、对象方法
对象可以包含函数类型的属性,也叫方法。
在接口中定义方法
interface Calculator {
add: (a: number, b: number) => number;
subtract(a: number, b: number): number;
}
let calc: Calculator = {
add: (a, b) => a + b,
subtract(a, b) {
return a – b;
}
};
add: (a: number, b: number) => number;
subtract(a: number, b: number): number;
}
let calc: Calculator = {
add: (a, b) => a + b,
subtract(a, b) {
return a – b;
}
};
在类型别名中定义方法
type CalculatorType = {
multiply: (a: number, b: number) => number;
divide(a: number, b: number): number;
}
multiply: (a: number, b: number) => number;
divide(a: number, b: number): number;
}
提示: 定义方法时,箭头函数写法和传统写法都可以,选择一种并保持代码风格一致。