TypeScript变量声明知识点汇总
编程小白也能看懂的TypeScript变量声明指南,用大白话讲解核心概念
变量声明方式
在TypeScript中,声明变量有三种方式:
- var – 老式声明方式(不推荐使用)
- let – 块级作用域变量(推荐)
- const – 声明常量(值不能变)
大白话:把 let
想象成可更改的便签,const
就是固定住的标签。
const fixed = “我不能被改变”; // 赋值后就不能再改
// 尝试改变常量会报错
fixed = “新值”; // 错误!
最佳实践:优先使用const
,当需要改变变量值时才使用let
。
类型注解
TypeScript允许给变量添加类型注解,明确变量可以存储什么类型的数据。
大白话:就像给盒子贴标签,说明里面应该放什么类型的东西。
let name: string = “张三”;
let age: number = 25;
let isStudent: boolean = true;
// 数组类型
let hobbies: string[] = [“编程”, “阅读”];
let scores: Array<number> = [98, 87, 92];
// 错误的类型会报错
name = 30; // 错误!不能把数字赋值给字符串变量
为什么重要:类型注解可以帮助你在写代码时就发现错误,而不是等到运行时。
类型推断
TypeScript很聪明,如果你声明变量时直接赋值,它会自动推断出变量类型。
大白话:TypeScript能根据你放进去的东西猜出盒子里是什么类型。
let name = “李四”;
name = 42; // 错误!不能把数字赋值给字符串变量
// 自动推断数组类型
let numbers = [1, 2, 3]; // 推断为number[]
numbers.push(“四”); // 错误!不能添加字符串到数字数组
最佳实践:在可以推断类型的地方,可以省略类型注解,让代码更简洁。
对象类型
TypeScript中,对象类型可以精确地定义对象应该有哪些属性以及属性的类型。
大白话:就像填写表格时,规定好每个字段应该填什么内容。
let person: {
name: string;
age: number;
isStudent?: boolean; // 可选属性
} = {
name: “王五”,
age: 30
};
// 缺少必需属性会报错
let invalidPerson: { name: string; age: number } = {
name: “赵六”
}; // 错误!缺少age属性
可选属性:在属性名后面加?
表示该属性可有可无。
联合类型
一个变量可以是多种类型中的一种,使用|
分隔多个类型。
大白话:这个盒子可以放书也可以放笔记本,但不能放其他东西。
let id: string | number = “ABC123”;
id = 12345; // 允许赋值为数字
// 联合类型数组
let mixedArray: (string | number)[] = [“苹果”, 5, “香蕉”, 8];
// 类型检查
if (typeof id === “string”) {
console.log(id.toUpperCase()); // 安全调用字符串方法
}
使用typeof
类型检查可以在联合类型中安全地访问特定类型的方法和属性。
解构赋值
解构赋值让你可以从数组或对象中提取数据,赋值给不同的变量。
大白话:就像拆快递包裹,把里面的东西拿出来单独存放。
let colors: string[] = [“红”, “绿”, “蓝”];
let [firstColor, secondColor] = colors;
console.log(firstColor); // “红”
// 对象解构
let person = { name: “小明”, age: 20 };
let { name, age } = person;
console.log(name); // “小明”
// 重命名变量
let { name: personName, age: personAge } = person;
解构赋值在函数参数中也特别有用,可以清晰地看到函数需要哪些属性。
展开运算符
展开运算符...
可以将数组或对象展开为单独的元素或属性。
大白话:就像把一本书的书页拆开,或者把多个包裹合并成一个大包裹。
let arr1 = [1, 2, 3];
let arr2 = [4, 5, 6];
let combined = […arr1, …arr2]; // [1,2,3,4,5,6]
// 展开对象
let person = { name: “张三”, age: 25 };
let employee = { …person, job: “工程师” };
// { name: “张三”, age: 25, job: “工程师” }
// 覆盖属性
let updatedPerson = { …person, age: 26 }; // 更新年龄
展开运算符是创建数组或对象副本的首选方式,因为它不会修改原始数据。
类型别名与接口
当对象结构复杂时,可以使用类型别名(type
)或接口(interface
)来简化重复的类型定义。
大白话:给复杂的类型结构起个简单好记的名字。
type Person = {
name: string;
age: number;
isStudent?: boolean;
};
// 使用接口定义类型
interface IPerson {
name: string;
age: number;
isStudent?: boolean;
}
// 使用定义好的类型
let person1: Person = { name: “李四”, age: 30 };
let person2: IPerson = { name: “王五”, age: 25, isStudent: true };
type vs interface:两者功能相似,但接口更适合定义对象结构,且可以被扩展(extends
)。
类型断言
当你知道一个值的类型但TypeScript不知道时,可以使用类型断言告诉TypeScript你确定的类型。
大白话:你比TypeScript更清楚盒子里是什么,告诉它:”相信我,这就是XX类型!”
let element = document.getElementById(“my-input”);
// element 被推断为 HTMLElement | null
// 使用类型断言告诉TS这是一个输入框
let input = document.getElementById(“my-input”) as HTMLInputElement;
console.log(input.value); // 现在可以访问value属性
// 另一种语法(在JSX中不可用)
let anotherInput = <HTMLInputElement>document.getElementById(“another-input”);
注意:类型断言不会改变运行时的值,只是告诉TypeScript如何理解这个值。