Appearance
TypeScript 基本结构
TypeScript 程序的基本结构与 JavaScript 类似,但添加了一些额外的组织方式,如模块、命名空间、接口和类等。本文将介绍 TypeScript 程序的基本结构。
1. 基本组成
一个 TypeScript 程序通常由以下部分组成:
- 导入语句:用于导入其他模块或库
- 变量声明:声明变量和常量
- 函数声明:定义函数
- 类声明:定义类
- 接口声明:定义接口
- 命名空间声明:定义命名空间
- 导出语句:用于导出模块成员
- 执行代码:程序的主要逻辑
2. 简单的 TypeScript 程序
以下是一个简单的 TypeScript 程序示例:
typescript
// 导入语句
import * as fs from 'fs';
// 变量声明
const message: string = "Hello, TypeScript!";
// 函数声明
function greet(name: string): string {
return `Hello, ${name}!`;
}
// 类声明
class Person {
private name: string;
private age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
public greet(): string {
return `Hello, my name is ${this.name} and I am ${this.age} years old.`;
}
}
// 接口声明
interface Animal {
name: string;
makeSound(): void;
}
// 命名空间声明
namespace MathUtils {
export function add(a: number, b: number): number {
return a + b;
}
export function subtract(a: number, b: number): number {
return a - b;
}
}
// 导出语句
export { Person, Animal, MathUtils };
// 执行代码
console.log(message);
console.log(greet("John"));
const person = new Person("John", 30);
console.log(person.greet());
console.log(MathUtils.add(1, 2));3. 入口点
在 TypeScript 中,程序的入口点通常是一个包含 main 函数或直接执行代码的文件。当你编译并运行 TypeScript 程序时,编译器会从入口点开始执行。
示例:带有 main 函数的程序
typescript
// app.ts
function main(): void {
console.log("Hello, TypeScript!");
// 程序的主要逻辑
}
// 调用 main 函数
main();示例:直接执行的程序
typescript
// app.ts
console.log("Hello, TypeScript!");
// 直接执行的代码
const name: string = "John";
console.log(`Hello, ${name}!`);4. 模块结构
TypeScript 支持 ES 模块系统,使用 import 和 export 语句来组织代码。模块是代码组织的基本单位,每个模块都有自己的作用域。
模块的基本结构
typescript
// math.ts
// 导出函数
export function add(a: number, b: number): number {
return a + b;
}
export function subtract(a: number, b: number): number {
return a - b;
}
// 导出常量
export const PI: number = 3.14159;
// 导出类型
export interface Point {
x: number;
y: number;
}
// app.ts
// 导入模块成员
import { add, subtract, PI, Point } from "./math";
// 使用导入的成员
console.log(add(1, 2)); // 3
console.log(subtract(5, 3)); // 2
console.log(PI); // 3.14159
const point: Point = { x: 10, y: 20 };
console.log(point); // { x: 10, y: 20 }默认导出
模块可以有一个默认导出,使用 export default 语法:
typescript
// math.ts
export default function multiply(a: number, b: number): number {
return a * b;
}
// app.ts
import multiply from "./math";
console.log(multiply(2, 3)); // 6导入所有成员
可以使用 * as 语法导入模块的所有成员:
typescript
// app.ts
import * as MathUtils from "./math";
console.log(MathUtils.add(1, 2)); // 3
console.log(MathUtils.subtract(5, 3)); // 2
console.log(MathUtils.PI); // 3.141595. 命名空间
命名空间是 TypeScript 中另一种组织代码的方式,它允许你将相关的代码组织在一起,避免命名冲突。
命名空间的基本结构
typescript
// utils.ts
namespace Utils {
export function formatDate(date: Date): string {
return date.toISOString();
}
export function formatCurrency(amount: number): string {
return `$${amount.toFixed(2)}`;
}
}
// app.ts
// 使用命名空间中的函数
console.log(Utils.formatDate(new Date()));
console.log(Utils.formatCurrency(100));嵌套命名空间
命名空间可以嵌套,以创建更复杂的代码组织:
typescript
// utils.ts
namespace Utils {
export namespace DateUtils {
export function formatDate(date: Date): string {
return date.toISOString();
}
export function parseDate(dateString: string): Date {
return new Date(dateString);
}
}
export namespace CurrencyUtils {
export function formatCurrency(amount: number): string {
return `$${amount.toFixed(2)}`;
}
export function parseCurrency(currencyString: string): number {
return parseFloat(currencyString.replace('$', ''));
}
}
}
// app.ts
console.log(Utils.DateUtils.formatDate(new Date()));
console.log(Utils.CurrencyUtils.formatCurrency(100));6. 类和接口的组织
在 TypeScript 中,类和接口是组织代码的重要方式。它们可以帮助你创建更结构化、更可维护的代码。
类的基本结构
typescript
// person.ts
export class Person {
private name: string;
private age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
public getName(): string {
return this.name;
}
public getAge(): number {
return this.age;
}
public setName(name: string): void {
this.name = name;
}
public setAge(age: number): void {
this.age = age;
}
public greet(): string {
return `Hello, my name is ${this.name} and I am ${this.age} years old.`;
}
}
// app.ts
import { Person } from "./person";
const person = new Person("John", 30);
console.log(person.greet()); // Hello, my name is John and I am 30 years old.
person.setName("Jane");
person.setAge(25);
console.log(person.greet()); // Hello, my name is Jane and I am 25 years old.接口的基本结构
typescript
// animal.ts
export interface Animal {
name: string;
makeSound(): void;
}
export class Dog implements Animal {
public name: string;
constructor(name: string) {
this.name = name;
}
public makeSound(): void {
console.log("Woof! Woof!");
}
}
export class Cat implements Animal {
public name: string;
constructor(name: string) {
this.name = name;
}
public makeSound(): void {
console.log("Meow! Meow!");
}
}
// app.ts
import { Animal, Dog, Cat } from "./animal";
function letAnimalSpeak(animal: Animal): void {
console.log(`${animal.name} says:`);
animal.makeSound();
}
const dog = new Dog("Buddy");
const cat = new Cat("Whiskers");
letAnimalSpeak(dog); // Buddy says: Woof! Woof!
letAnimalSpeak(cat); // Whiskers says: Meow! Meow!7. 代码组织最佳实践
1. 使用模块组织代码
将相关的代码组织到模块中,每个模块负责一个特定的功能。
src/
├── utils/
│ ├── math.ts
│ ├── date.ts
│ └── index.ts
├── models/
│ ├── person.ts
│ ├── animal.ts
│ └── index.ts
├── services/
│ ├── userService.ts
│ ├── productService.ts
│ └── index.ts
├── components/
│ ├── button.ts
│ ├── input.ts
│ └── index.ts
├── app.ts
└── index.ts2. 使用接口定义类型
使用接口定义数据结构和类型,提高代码的可读性和可维护性。
typescript
// 定义用户接口
interface User {
id: number;
name: string;
email: string;
age?: number;
}
// 使用接口
function getUser(id: number): User {
return {
id,
name: "John",
email: "john@example.com"
};
}3. 使用类封装逻辑
使用类封装相关的属性和方法,提高代码的组织性和可重用性。
typescript
class UserService {
private users: User[] = [];
public addUser(user: User): void {
this.users.push(user);
}
public getUser(id: number): User | undefined {
return this.users.find(user => user.id === id);
}
public updateUser(id: number, updates: Partial<User>): void {
const index = this.users.findIndex(user => user.id === id);
if (index !== -1) {
this.users[index] = { ...this.users[index], ...updates };
}
}
public deleteUser(id: number): void {
this.users = this.users.filter(user => user.id !== id);
}
}4. 使用命名空间组织相关代码
使用命名空间组织相关的代码,避免命名冲突。
typescript
namespace Validation {
export function validateEmail(email: string): boolean {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailRegex.test(email);
}
export function validatePassword(password: string): boolean {
return password.length >= 8;
}
}
// 使用命名空间中的函数
console.log(Validation.validateEmail("john@example.com")); // true
console.log(Validation.validatePassword("password123")); // true5. 使用类型别名简化复杂类型
使用类型别名简化复杂的类型定义,提高代码的可读性。
typescript
type UserId = number;
type UserName = string;
type Email = string;
type User = {
id: UserId;
name: UserName;
email: Email;
age?: number;
};
function getUser(id: UserId): User {
return {
id,
name: "John",
email: "john@example.com"
};
}8. 项目结构示例
小型项目结构
my-app/
├── src/
│ ├── utils.ts
│ ├── models.ts
│ ├── app.ts
│ └── index.ts
├── package.json
├── tsconfig.json
└── README.md中型项目结构
my-app/
├── src/
│ ├── utils/
│ │ ├── math.ts
│ │ ├── date.ts
│ │ └── index.ts
│ ├── models/
│ │ ├── user.ts
│ │ ├── product.ts
│ │ └── index.ts
│ ├── services/
│ │ ├── userService.ts
│ │ ├── productService.ts
│ │ └── index.ts
│ ├── components/
│ │ ├── button.tsx
│ │ ├── input.tsx
│ │ └── index.ts
│ ├── pages/
│ │ ├── home.tsx
│ │ ├── about.tsx
│ │ └── index.ts
│ ├── app.tsx
│ └── index.tsx
├── public/
│ ├── index.html
│ └── favicon.ico
├── package.json
├── tsconfig.json
├── webpack.config.js
└── README.md9. 编译和运行 TypeScript 程序
编译 TypeScript 文件
使用 tsc 命令编译 TypeScript 文件:
bash
tsc app.ts这会生成一个 app.js 文件,然后你可以使用 node 命令运行它:
bash
node app.js使用 tsconfig.json
创建一个 tsconfig.json 文件来配置编译选项:
json
{
"compilerOptions": {
"target": "es2016",
"module": "commonjs",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true,
"outDir": "./dist"
},
"include": ["./src/**/*"]
}然后运行 tsc 命令编译整个项目:
bash
tsc这会将编译后的文件输出到 dist 目录中。
总结
TypeScript 程序的基本结构包括:
- 基本组成:导入语句、变量声明、函数声明、类声明、接口声明、命名空间声明、导出语句和执行代码
- 入口点:程序的起始执行点
- 模块结构:使用 ES 模块系统组织代码
- 命名空间:用于组织相关代码,避免命名冲突
- 类和接口:用于创建结构化、可维护的代码
- 代码组织最佳实践:使用模块、接口、类和命名空间组织代码
- 项目结构:根据项目大小和复杂度组织文件结构
通过合理组织 TypeScript 代码,你可以创建更结构化、更可维护、更易于理解的程序。