ts跟js写法

admin 104 0
TypeScript(TS)作为JavaScript(JS)的超集,核心差异在于类型系统,JS写法灵活,变量直接声明赋值(如let name = "Alice"),函数无需类型标注;TS则需显式类型注解(如let name: string = "Alice"),函数参数及返回值需声明类型(如function add(a: number, b: number): number),TS支持接口、枚举、泛型等JS缺失的特性(如interface User { id: number }),增强代码规范性,减少运行时错误,JS适合快速开发,TS更适合大型项目,需编译为JS运行,两者语法高度兼容,TS可逐步引入类型。

TypeScript与JavaScript:语法写法对比与实战指南

在Web开发领域,JavaScript(以下简称JS)作为前端开发的基石,以其灵活性和动态特性支撑了无数项目的运行,随着项目规模扩大、复杂度提升,JS的动态类型特性逐渐暴露出维护困难、运行时错误频发等问题,TypeScript(以下简称TS)作为JS的超集,通过引入静态类型系统,在保留JS核心语法的同时,提供了更严格的代码约束和更好的开发体验,本文将从核心语法写法入手,深入对比TS与JS的差异,帮助开发者理解两者的优劣与应用场景。

基础语法写法:从"自由"到"规范"

变量声明与类型注解

JavaScript的变量声明依赖letconstvar,类型完全由运行时值决定:

let name = "Alice";  // 类型推断为string
const age = 25;      // 类型推断为number
var isAdmin = true;  // 类型推断为boolean

TypeScript允许显式声明类型,或通过类型推断自动识别:

let name: string = "Alice";  // 显式声明string类型
const age: number = 25;      // 显式声明number类型
var isAdmin: boolean = true; // 显式声明boolean类型
// TS会检查类型匹配,以下代码会报错:
name = 123;  // Error: Type 'number' is not assignable to type 'string'

核心差异:TS通过类型注解在编译阶段捕获类型错误,而JS只能在运行时发现问题,这种"提前发现"的特性大大减少了生产环境的bug数量。

函数定义:参数与返回值的类型约束

JavaScript函数对参数和返回值类型无限制:

function add(a, b) {
  return a + b;
}
add(1, "2");  // 返回"12"(字符串拼接),运行时才暴露问题

TypeScript函数可明确参数类型和返回值类型,编译器会校验参数匹配:

function add(a: number, b: number): number {
  return a + b;
}
add(1, "2");  // Error: Argument of type 'string' is not assignable to parameter of type 'number'

优势:TS函数的"签名"清晰,调用时IDE能提供智能提示,减少低级错误,在实际项目中,这种类型约束能显著提高代码的可维护性。

对象与数组:结构化类型定义

JavaScript对象和数组是动态的,可随时增删属性:

const user = { name: "Bob", age: 30 };
user.gender = "male";  // 动态添加属性
const numbers = [1, 2, "3"];  // 数组元素类型可混用

TypeScript通过接口(interface)和类型别名(type)定义对象结构,约束属性类型:

interface User {
  name: string;
  age: number;
  gender?: string;  // ?表示可选属性
}
const user: User = { name: "Bob", age: 30 };
user.gender = "male";  // 允许添加可选属性
// user.email = "test@example.com";  // Error: Property 'email' does not exist on type 'User'
// 数组元素类型需统一
const numbers: number[] = [1, 2, 3];
const mixedArray: (number | string)[] = [1, 2, "3"];  // 联合类型允许多种元素

核心差异:TS通过"结构化类型系统"确保对象/数组结构符合预期,避免运行时属性访问错误,这种特性在大型项目中尤为重要,能有效防止因对象结构变化导致的连锁错误。

类与继承:访问修饰符与类型约束

JavaScript的类(ES6+)支持基本面向对象特性,但缺乏访问控制:

class Animal {
  constructor(name) {
    this.name = name;  // 属性默认公开
  }
  eat() {
    console.log(`${this.name} is eating`);
  }
}
class Dog extends Animal {
  bark() {
    console.log("Woof!");
  }
}
const dog = new Dog("Buddy");
dog.name = "Cat";  // 可随意修改公开属性

TypeScript类支持访问修饰符(publicprivateprotected),并约束属性类型:

class Animal {
  public name: string;  // 默认public,允许外部访问
  private age: number;  // private,仅类内部访问
  protected category: string;  // protected,类及子类可访问
  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
    this.category = "mammal";
  }
  eat() {
    console.log(`${this.name} is eating`);
  }
}
class Dog extends Animal {
  bark() {
    console.log("Woof!");
    // console.log(this.age);  // Error: Property 'age' is private and only accessible within class 'Animal'
    console.log(this.category);  // 允许访问protected属性
  }
}
const dog = new Dog("Buddy", 3);
// dog.age = 5;  // Error: Property 'age' is private and only accessible within class 'Animal'

优势:TS通过访问修饰符封装内部状态,提升代码安全性;类型约束确保类属性/方法符合预期,这种封装性在团队协作开发中尤为重要。

泛型:灵活的类型抽象

JavaScript无法在编译时约束类型参数,而TS通过泛型实现"类型参数化":

// 定义泛型函数,确保输入输出类型一致
function identity<T>(arg: T): T {
  return arg;
}
const output1 = identity<string>("hello");  // 显式指定T为string
const output2 = identity(123);              // 类型推断T为number
// 泛型接口
interface Container<T> {
  value: T;
}
const numberContainer: Container<number> = { value: 123 };
const stringContainer: Container<string> = { value: "hello" };

核心价值:泛型让TS既保持灵活性,又具备类型安全,适用于工具函数、数据结构等场景,在实际开发中,泛型是TS最强大的特性之一,使得代码既类型安全又高度可复用。

实战应用:从JS到TS的迁移

类型定义文件(.d.ts)

在从JS迁移到TS时,可以使用类型定义文件来逐步引入类型:

// 假设有一个JS库:utils.js
// utils.d.ts
export function formatDate(date: Date): string;
export function debounce<T extends (...args: any[]) => any>(
  func: T,
  wait: number
): T;

工具链配置

tsconfig.json配置示例:

{
  "compilerOptions": {
    "target": "ES2020",
    "module": "ESNext",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules"]
}

实际案例:React组件类型化

import React from 'react';
interface UserCardProps {
  user: {
    id

标签: #JavaScript语法