91网首页-91网页版-91网在线观看-91网站免费观看-91网站永久视频-91网站在线播放

LOGO OA教程 ERP教程 模切知識交流 PMS教程 CRM教程 開發(fā)文檔 其他文檔  
 
網(wǎng)站管理員

TypeScript對比JavaScript,有哪些核心區(qū)別和優(yōu)勢

admin
2025年3月31日 16:54 本文熱度 653

JavaScript對比TypeScript

作為一名 JavaScript 工程師,我經(jīng)常被問到:"為什么要使用 TypeScript?"或者"TypeScript 相比 JavaScript 有什么優(yōu)勢?"今天,讓我們通過實際的代碼示例來深入探討這個話題。

核心特性對比

1. 類型系統(tǒng):最顯著的區(qū)別

?javascript

// JavaScript function calculateTotal(items) { return items.reduce((total, item) => total + item.price, 0); } // 這段代碼可能在運行時出錯 const items = [ { price: 10 }, { price: 20 }, { notPrice: 30 } // 這里會導(dǎo)致運行時錯誤 ]; console.log(calculateTotal(items)); // 運行時才發(fā)現(xiàn) undefined + number 的錯誤

typescript

// TypeScript interface Item { price: number; } function calculateTotal(items: Item[]): number { return items.reduce((total, item) => total + item.price, 0); } // 在編譯時就會發(fā)現(xiàn)錯誤 const items = [ { price: 10 }, { price: 20 }, { notPrice: 30 } // TypeScript 會在編譯時報錯! ];

2. 接口和類型定義

javascript

// JavaScript const user = { name: 'John', age: 30, address: { street: '123 Main St', city: 'Boston' } }; // 沒有明確的契約,可能導(dǎo)致使用時的不確定性 function updateUser(user) { // 這里我們并不確定 user 對象應(yīng)該包含哪些屬性 user.name = 'Jane'; }

typescript

// TypeScript interface Address { street: string; city: string; zipCode?: string; // 可選屬性 } interface User { name: string; age: number; address: Address; } function updateUser(user: User): void { user.name = 'Jane'; // IDE 會提供完整的屬性提示 }

3. 函數(shù)重載

javascript

// JavaScript function process(input) { if (typeof input === 'string') { return input.toUpperCase(); } else if (Array.isArray(input)) { return input.map(item => item.toUpperCase()); } throw new Error('Unsupported input type'); }

typescript

// TypeScript function process(input: string): string; function process(input: string[]): string[]; function process(input: string | string[]): string | string[] { if (typeof input === 'string') { return input.toUpperCase(); } else { return input.map(item => item.toUpperCase()); } }

4. 泛型

javascript

// JavaScript function firstElement(arr) { return arr[0]; } // 無法在編譯時確保類型安全 const numResult = firstElement([1, 2, 3]); const strResult = firstElement(['a', 'b', 'c']);

typescript

// TypeScript function firstElement<T>(arr: T[]): T | undefined { return arr[0]; } // 類型安全且具有更好的 IDE 支持 const numResult = firstElement([1, 2, 3]); // 類型為 number const strResult = firstElement(['a', 'b', 'c']); // 類型為 string

TypeScript 特有的語法特性

1. 類型注解(Type Annotations)

javascript

// JavaScript let name = "John"; let age = 30; let isStudent = true; let numbers = [1, 2, 3]; // JavaScript 中沒有元組類型,使用普通數(shù)組 let tuple = ["hello", 10]; // JavaScript 中可以使用 JSDoc 注釋來提供類型信息 /** * @param {string} name * @returns {string} */ function greet(name) { return `Hello, ${name}!`; }

typescript

// TypeScript let name: string = "John"; let age: number = 30; let isStudent: boolean = true; let numbers: number[] = [1, 2, 3]; let tuple: [string, number] = ["hello", 10]; // 函數(shù)參數(shù)和返回值的類型注解 function greet(name: string): string { return `Hello, ${name}!`; }

2. 枚舉(Enums)

javascript

// JavaScript 實現(xiàn)方式 1:使用對象 const Direction = { Up: "UP", Down: "DOWN", Left: "LEFT", Right: "RIGHT", // 防止枚舉值被修改 Object.freeze(Direction); }; // JavaScript 實現(xiàn)方式 2:使用 Symbol const Direction = { Up: Symbol("UP"), Down: Symbol("DOWN"), Left: Symbol("LEFT"), Right: Symbol("RIGHT") }; let playerDirection = Direction.Up; // 數(shù)字枚舉的實現(xiàn) const StatusCode = { OK: 200, NotFound: 404, Error: 500, Object.freeze(StatusCode); };

typescript

// TypeScript enum Direction { Up = "UP", Down = "DOWN", Left = "LEFT", Right = "RIGHT" } let playerDirection: Direction = Direction.Up; // 數(shù)字枚舉 enum StatusCode { OK = 200, NotFound = 404, Error = 500 }

3. 類型斷言(Type Assertions)

javascript

// JavaScript let someValue = "this is a string"; let strLength = someValue.length; // JavaScript 中使用類型檢查 if (typeof someValue === 'string') { let strLength = someValue.length; } // DOM 操作 const myCanvas = document.getElementById('main_canvas'); if (myCanvas instanceof HTMLCanvasElement) { // 使用 canvas API const ctx = myCanvas.getContext('2d'); }

typescript

// TypeScript let someValue: any = "this is a string"; let strLength: number = (someValue as string).length; // 或者 let strLength: number = (<string>someValue).length; // DOM 操作的類型斷言 const myCanvas = document.getElementById('main_canvas') as HTMLCanvasElement;

4. 訪問修飾符

javascript

// JavaScript class Employee { #name; // 私有字段(ES2019+) _age; // 約定俗成的protected字段 department; constructor(name, age, department, id) { this.#name = name; this._age = age; this.department = department; Object.defineProperty(this, 'id', { value: id, writable: false // 實現(xiàn) readonly }); } #getDetails() { // 私有方法(ES2019+) return `${this.#name} (${this._age})`; } }

typescript

// TypeScript class Employee { private name: string; protected age: number; public department: string; readonly id: number; constructor(name: string, age: number, department: string, id: number) { this.name = name; this.age = age; this.department = department; this.id = id; } private getDetails(): string { return `${this.name} (${this.age})`; } }

5. 抽象類和接口

javascript

// JavaScript // 模擬抽象類 class Animal { constructor() { if (new.target === Animal) { throw new Error('Animal is abstract'); } } makeSound() { throw new Error('makeSound must be implemented'); } move() { console.log("Moving..."); } } // 模擬接口 class Pet { constructor() { if (this.play === undefined) { throw new Error('Must implement play method'); } if (!this.name) { throw new Error('Must have name property'); } } } class Dog extends Animal { constructor(name) { super(); this.name = name; } makeSound() { console.log("Woof!"); } play() { console.log("Playing fetch!"); } }

typescript

// TypeScript abstract class Animal { abstract makeSound(): void; move(): void { console.log("Moving..."); } } interface Pet { name: string; play(): void; } class Dog extends Animal implements Pet { name: string; constructor(name: string) { super(); this.name = name; } makeSound(): void { console.log("Woof!"); } play(): void { console.log("Playing fetch!"); } }

6. 聯(lián)合類型和交叉類型

javascript

// JavaScript function processValue(value) { if (typeof value === "string") { return value.toUpperCase(); } if (typeof value === "number") { return value * 2; } throw new Error('Invalid type'); } // 對象合并 const person = { ...{ name: "John" }, ...{ age: 30 } };

typescript

// TypeScript type StringOrNumber = string | number; type NameAndAge = { name: string } & { age: number }; function processValue(value: StringOrNumber) { if (typeof value === "string") { return value.toUpperCase(); } return value * 2; } const person: NameAndAge = { name: "John", age: 30 };

7. 可選鏈和空值合并

javascript

// JavaScript ES2020+ const user = { name: "John" }; // 可選鏈 const city = user.address?.city; // 空值合并 const street = user.address?.street ?? "Default Street"; // 舊版 JavaScript const city = user && user.address && user.address.city; const street = (user && user.address && user.address.street) || "Default Street";

typescript

// TypeScript(也適用于現(xiàn)代 JavaScript) interface User { name: string; address?: { street?: string; city?: string; }; } const user: User = { name: "John" }; // 可選鏈 const city = user.address?.city; // 空值合并 const street = user.address?.street ?? "Default Street";

8. 字面量類型

javascript

// JavaScript const CARDINAL_DIRECTIONS = ["North", "South", "East", "West"]; const DICE_VALUES = [1, 2, 3, 4, 5, 6]; function move(direction) { if (!CARDINAL_DIRECTIONS.includes(direction)) { throw new Error('Invalid direction'); } console.log(`Moving ${direction}`); } move("North"); // 有效 move("Northeast"); // 運行時錯誤

typescript

// TypeScript type CardinalDirection = "North" | "South" | "East" | "West"; type DiceRoll = 1 | 2 | 3 | 4 | 5 | 6; function move(direction: CardinalDirection) { console.log(`Moving ${direction}`); } move("North"); // 有效 // move("Northeast"); // 編譯錯誤

9. 類型別名和映射類型

javascript

// JavaScript const createPoint = (x, y) => ({ x, y }); // 創(chuàng)建只讀對象 const createReadonlyPoint = (x, y) => Object.freeze({ x, y }); const point = createReadonlyPoint(10, 20); // point.x = 30; // 錯誤:Cannot assign to read only property 'x'

typescript

// TypeScript type Point = { x: number; y: number; }; type Readonly<T> = { readonly [P in keyof T]: T[P]; }; type ReadonlyPoint = Readonly<Point>; const point: ReadonlyPoint = { x: 10, y: 20 }; // point.x = 30; // 錯誤:無法分配到 "x" ,因為它是只讀屬性

10. 裝飾器(Decorators)

javascript

// JavaScript(使用實驗性的裝飾器語法) function log(target, propertyKey) { console.log(`Accessing property: ${propertyKey}`); } class Example { @log name = "example"; } // JavaScript(不使用裝飾器的替代方案) function makeLoggable(target) { const originalDescriptor = Object.getOwnPropertyDescriptor(target.prototype, 'name'); Object.defineProperty(target.prototype, 'name', { get() { console.log('Accessing property: name'); return originalDescriptor.get.call(this); }, set(value) { console.log('Setting property: name'); originalDescriptor.set.call(this, value); } }); return target; } @makeLoggable class Example { name = "example"; }

typescript

// TypeScript function log(target: any, propertyKey: string) { console.log(`Accessing property: ${propertyKey}`); } class Example { @log name: string = "example"; }

這些語法特性使得 TypeScript 能夠:

  1. 提供更強(qiáng)大的類型檢查和編譯時驗證
  2. 支持面向?qū)ο缶幊痰母呒壧匦?/li>
  3. 提供更好的代碼組織和重用機(jī)制
  4. 增強(qiáng)代碼的可讀性和可維護(hù)性
  5. 提供更好的 IDE 支持和開發(fā)體驗

雖然很多特性在現(xiàn)代 JavaScript 中也可以實現(xiàn),但實現(xiàn)方式往往更復(fù)雜,且缺少編譯時的類型檢查。TypeScript 的優(yōu)勢在于它提供了更簡潔、更安全的語法,以及強(qiáng)大的類型系統(tǒng)支持。

如何在項目中使用 TypeScript

1. 初始化項目

bash

# 創(chuàng)建新項目 mkdir my-ts-project cd my-ts-project npm init -y # 安裝 TypeScript npm install typescript --save-dev # 初始化 TypeScript 配置 npx tsc --init

2. 配置 tsconfig.json

json

{ "compilerOptions": { "target": "es2020", "module": "commonjs", "strict": true, "esModuleInterop": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true, "outDir": "./dist", "rootDir": "./src" }, "include": ["src/**/*"], "exclude": ["node_modules"] }

3. 項目結(jié)構(gòu)

css

my-ts-project/ ├── src/ │ └── index.ts ├── package.json ├── tsconfig.json └── node_modules/

4. 開發(fā)工作流

  1. 編寫 TypeScript 代碼(.ts 文件)
  2. 使用 tsc 編譯代碼:npx tsc
  3. 運行編譯后的 JavaScript 代碼:node dist/index.js

5. 推薦的開發(fā)工具

  • VS Code:內(nèi)置 TypeScript 支持
  • ESLint 配置:

bash

npm install --save-dev @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint

總結(jié)

TypeScript 相比 JavaScript 的主要優(yōu)勢:

  1. 靜態(tài)類型檢查,提前發(fā)現(xiàn)潛在錯誤
  2. 更好的 IDE 支持,包括代碼補(bǔ)全和重構(gòu)
  3. 接口和類型定義提供更清晰的代碼契約
  4. 更容易維護(hù)大型項目
  5. 通過類型推斷減少文檔需求

雖然需要一些學(xué)習(xí)成本,但 TypeScript 帶來的好處遠(yuǎn)超過這些成本,特別是在大型項目中。作為一個 JavaScript 工程師,掌握 TypeScript 將顯著提升你的開發(fā)效率和代碼質(zhì)量。


作者:AI編程產(chǎn)品人
鏈接:https://juejin.cn/post/7477104460452675594
來源:稀土掘金
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。

該文章在 2025/4/1 13:16:43 編輯過
點晴ERP是一款針對中小制造業(yè)的專業(yè)生產(chǎn)管理軟件系統(tǒng),系統(tǒng)成熟度和易用性得到了國內(nèi)大量中小企業(yè)的青睞。
點晴PMS碼頭管理系統(tǒng)主要針對港口碼頭集裝箱與散貨日常運作、調(diào)度、堆場、車隊、財務(wù)費用、相關(guān)報表等業(yè)務(wù)管理,結(jié)合碼頭的業(yè)務(wù)特點,圍繞調(diào)度、堆場作業(yè)而開發(fā)的。集技術(shù)的先進(jìn)性、管理的有效性于一體,是物流碼頭及其他港口類企業(yè)的高效ERP管理信息系統(tǒng)。
點晴WMS倉儲管理系統(tǒng)提供了貨物產(chǎn)品管理,銷售管理,采購管理,倉儲管理,倉庫管理,保質(zhì)期管理,貨位管理,庫位管理,生產(chǎn)管理,WMS管理系統(tǒng),標(biāo)簽打印,條形碼,二維碼管理,批號管理軟件。
點晴免費OA是一款軟件和通用服務(wù)都免費,不限功能、不限時間、不限用戶的免費OA協(xié)同辦公管理系統(tǒng)。
Copyright 2010-2025 ClickSun All Rights Reserved

主站蜘蛛池模板: 午夜福利区一区二区 | 岛国大片网站 | 成人亚欧网站 | 欧美三区日韩一 | 精品视频一区二区 | 国产精品夫妻在线 | 果冻文化传媒官网 | 飘雪影院手机免 | 欧美在线风情观看 | 91国产福利 | 九九色综| 日韩精品二三区 | 精品国产午夜精华 | 国产综合精品一区二 | 日韩美女网站在线看 | 九九九在左线观看 | 午夜男女福利 | 日韩亚洲制服丝 | 国产福利小视频在 | 日韩精品福利 | 日本乱理伦片在线观 | 91视频国产大片 | 欧美日韩一级国产 | 国产系列在线 | 琪琪色18| 国产极品喷 | 国产老熟女精品v | 三年片在线观看直播 | 97影院| 国产高清综合 | 国产亚洲免费视频 | 精品影视大全 | 99爱这里只有精品 | 午夜国产精品理论 | 国产91精品 | 三区高清 | 国产精品日产三 | 国产操缅甸女人 | 琪棋午夜理论免费 | 日韩老熟女一区二区 | 欧美性色黄 |