TypeScript (TS) 是 JavaScript (JS) 的超集,它保留了 JS 的所有功能,并在其基础上引入了一些强大的特性,主要是为了提升开发体验、代码质量和可维护性。以下是 TypeScript 的主要特性及其学习方法:
1. 类型系统
TS 的核心特性是静态类型检查。TS 在编译时检查类型,帮助发现潜在的错误。
示例:
// TypeScript
let age: number = 25; // 明确指定age是数字类型
age = "25"; // ❌ Error: Type 'string' is not assignable to type 'number'.
// JavaScript
let age = 25;
age = "25"; // ✅ No error, 但可能导致运行时错误。
学习要点:
- 学习基本类型:
number
,string
,boolean
,any
,unknown
,null
,undefined
等。 - 理解类型推断:TS 会根据初始值推断变量的类型,无需显式声明。
- 练习:尝试为常见的 JS 变量添加类型标注,并观察错误提示。
2. 接口 (Interfaces) 和类型别名 (Type Aliases)
TS 提供 interface
和 type
来定义对象的结构,使得代码更清晰。
示例:
// Interface 定义对象结构
interface User {
name: string;
age: number;
}
let user: User = { name: "Alice", age: 25 }; // ✅ 符合结构
user = { name: "Alice" }; // ❌ Error: Property 'age' is missing.
// Type Alias 定义类型
type Point = { x: number; y: number };
let position: Point = { x: 10, y: 20 }; // ✅
学习要点:
- 区别
interface
和type
,虽然它们功能类似,但在某些场景下存在差异。 - 练习:定义接口和类型别名,创建对象并尝试修改它们的属性。
3. 枚举 (Enums)
TS 支持枚举,用于定义一组有名字的常量。
示例:
enum Direction {
Up = 1,
Down,
Left,
Right,
}
let move: Direction = Direction.Up; // ✅
console.log(move); // 输出: 1
学习要点:
- 理解数字枚举和字符串枚举的区别。
- 练习:尝试用枚举管理一组常量。
4. 元组 (Tuples)
TS 支持元组,用于表示一个已知数量和类型的数组。
示例:
let tuple: [string, number] = ["Alice", 25]; // ✅
tuple = [25, "Alice"]; // ❌ Error: Type 'number' is not assignable to type 'string'.
学习要点:
- 学习如何定义和使用元组。
- 练习:将常见的键值对表示为元组。
5. 联合类型和类型守卫
TS 提供联合类型 (|
) 和类型守卫 (typeof
、instanceof
) 来处理不同的类型。
示例:
function printId(id: number | string) {
if (typeof id === "string") {
console.log(`ID: ${id.toUpperCase()}`); // 类型守卫确保这是字符串
} else {
console.log(`ID: ${id}`);
}
}
printId(123); // ✅ 输出: ID: 123
printId("abc"); // ✅ 输出: ID: ABC
学习要点:
- 理解
|
和类型守卫的用途。 - 练习:编写接受多种类型的函数,并用类型守卫处理逻辑。
6. 泛型 (Generics)
TS 支持泛型,可以创建灵活且可复用的组件或函数。
示例:
function identity<T>(arg: T): T {
return arg;
}
console.log(identity<string>("Hello")); // ✅ 输出: Hello
console.log(identity<number>(123)); // ✅ 输出: 123
学习要点:
- 理解
T
是一种占位符,可表示任意类型。 - 练习:尝试编写泛型函数和类。
7. 装饰器 (Decorators)
TS 提供实验性的装饰器语法,用于修改类或其成员的行为。
示例:
function Logger(target: any, propertyKey: string) {
console.log(`${propertyKey} was accessed`);
}
class MyClass {
@Logger
myMethod() {
console.log("Hello");
}
}
学习要点:
- 装饰器需要启用
experimentalDecorators
。 - 练习:尝试创建简单的类装饰器和方法装饰器。
8. 模块化和命名空间
TS 提供模块化支持,使代码更易组织和管理。
示例:
// module.ts
export const greet = (name: string) => `Hello, ${name}`;
// main.ts
import { greet } from "./module";
console.log(greet("Alice")); // ✅ 输出: Hello, Alice
学习要点:
- 学习
export
和import
的用法。 - 练习:分离代码到多个文件,并使用模块化管理它们。
9. 严格模式 (Strict Mode)
TS 提供多种严格模式选项,帮助编写更安全的代码。
示例:
// tsconfig.json
{
"compilerOptions": {
"strict": true
}
}
strictNullChecks
: 禁止将null
或undefined
赋值给非可选类型。noImplicitAny
: 禁止未显式标注类型的变量。
学习要点:
- 了解常见的严格模式选项。
- 练习:启用严格模式,分析代码中出现的问题并修复。
interface 和 type 区别:在 TypeScript 中,interface
和 type
都可以用来定义类型,但它们在某些功能和应用场景上有细微的区别。以下是它们的主要区别和使用建议:
1. 语法定义
两者的基本语法看起来很相似:
// 使用 interface 定义类型
interface User {
name: string;
age: number;
}
// 使用 type 定义类型
type User = {
name: string;
age: number;
};
2. 扩展方式
interface
支持扩展(继承)
interface
可以通过 extends
扩展另一个接口。
interface Person {
name: string;
}
interface Employee extends Person {
salary: number;
}
const emp: Employee = { name: "Alice", salary: 50000 }; // ✅
type
支持交叉类型
type
通过交叉类型(&
)组合多个类型。
type Person = {
name: string;
};
type Employee = Person & {
salary: number;
};
const emp: Employee = { name: "Alice", salary: 50000 }; // ✅
3. 声明合并
interface
支持声明合并
可以对同一个 interface
进行多次声明,TS 会将它们合并。
interface User {
name: string;
}
interface User {
age: number;
}
const user: User = { name: "Alice", age: 25 }; // ✅
type
不支持声明合并
如果重复声明 type
,会报错:
type User = {
name: string;
};
type User = {
age: number; // ❌ Error: Duplicate identifier 'User'.
};
4. 复杂类型表达
type
更适合复杂类型
type
支持联合类型、交叉类型、映射类型等复杂表达式,而 interface
不支持这些用法。
// 使用 type 定义联合类型
type ID = string | number;
// 使用 type 定义函数类型
type Callback = (message: string) => void;
interface
不支持直接定义联合类型或函数类型:
// ❌ Error: An interface cannot be a union type.
interface ID = string | number;
// ❌ Error: An interface cannot define a callable function type.
interface Callback {
(message: string): void;
}
5. 性能
interface
在 TS 编译器中有更好的性能优化,因为它是专门为定义结构化类型设计的。type
的复杂表达式可能会在复杂项目中略微增加编译开销。
6. 推荐使用场景
-
使用
interface
:- 定义对象的结构(特别是需要扩展时)。
- 定义类的约束(如定义类的形状或接口)。
-
使用
type
:- 定义联合类型、交叉类型、或函数类型。
- 需要映射类型或条件类型时。
总结
特性 | interface | type |
---|---|---|
继承/扩展 | extends | & (交叉类型) |
声明合并 | 支持 | 不支持 |
联合类型/函数类型 | 不支持 | 支持 |
编译性能 | 更优化 | 稍慢 |
使用场景 | 结构化类型 | 复杂类型/组合类型 |
如果你的需求是定义一个对象并可能需要扩展,优先选择 interface
。如果需要定义复杂的联合类型或函数类型,使用 type
更合适。
如果你想结合实例进一步学习,告诉我你的需求或代码,我可以帮你设计具体的场景!