TypeScript语法简述

TypeScript语法简述

概述

TypeScript 是微软开发的一款开源的编程语言,作为 JavaScript 的超集(superset)。

  • 渐进式类型系统:允许逐步添加类型约束
  • 编译时类型检查
  • 类型即文档:类型声明自带代码自解释性

基本特性

类型注解

一种轻量级的为函数或变量添加约束的方式。

let count: number = 10;

function sum(a: number, b: number): number
{
    return a + b;
}

静态类型检查

在编译阶段检查类型错误。

let age: number = 25;

age = "30";   // ❌ 编译错误:Type 'string' is not assignable to type 'number'

类型推断

自动推导未显式标注类型的变量。

let name = "Alice"; // 推断为 string 类型

const PI = 3.14;    // 推断为 3.14 字面量类型(当用 const 声明时)

类型系统

原始类型

类型 说明 举例
boolean 逻辑值 true/false let isDone: boolean = true;
number 双精度 64 位浮点数,支持二进制/八进制/十六进制字面量 let num: number = 12;
string UTF-16 字符串,支持模板字符串 let str: string = "Hello";
symbol 唯一不可变值,常用于对象属性键 const key: symbol = Symbol('meta');
null 空值(需开启 strictNullChecks 严格模式) let empty: null = null;
undefined 未定义值(通常用于可选参数) let uninit: undefined = undefined;

复合类型

类型 说明 举例
Array 相同类型元素的集合 let nums: number[] = [1,2,3];
let strs: Array<string> = ['a','b'];
Tuple 固定长度和类型的数组 let user: [string, number] = ['Alice', 25];
Enum 具名常量集合,支持数值/字符串枚举 enum Direction { Up, Down }
enum FileMode { Read = "r", Write = "w" }
Object 非原始类型的对象(包括数组、函数等) type User = { name: string };

特殊类型

graph TD A[顶层类型] --> B[any] A --> C[unknown] D[底层类型] --> E[never]
  • any:禁用类型检查
let dynamic: any = "可以赋任意值";
dynamic = 100;  // ✅ 
  • unknown:类型安全的 any,需显示类型检查后才能操作
let userInput: unknown = fetchData();
if(typeof userInput === "string")
{
    console.log(userInput.toUpperCase());
}
  • never:表示不可达代码
// 表示永远不会返回的终止行为
function error(msg: string): never
{
    throw new Error(msg);
}

function infiniteLoop(): never
{
    while(true)
    {
        /* do something ... */
    }
}
  • void:表示函数无返回值
function logMessage(msg: string): void
{
    console.log(msg);
}

扩展特性

类型断言

// 尖括号语法(JSX 中禁用)
let strLength: number = (<string>someValue).length;

// as 语法(推荐)
let strLength: number = (someValue as string).length;

类型守卫

function isNumber(x: any): x is number {
  return typeof x === "number";
}

if (isNumber(input)) {
  console.log(input.toFixed(2)); // ✅ 类型收窄为 number
}

高级类型

联合类型

表示一个值可以是多种类型之一。

type ID = string | number;
function printId(id: ID)
{
    if(typeof id === "string")
    {
        console.log(id.toUpperCase());
    }
    else
    {
        console.log(id.toFixed(2));
    }
}

交叉类型

将多个类型合并为一个类型。

type Admin = { name: string; privileges: string[] };
type Employee = { name: string; startDate: Date };
type AdminEmployee = Admin & Employee;

const adminEmp: AdminEmployee = {
    name: "Alice",
    privileges: ["create-server"],
    startDate: new Date()
};

类型别名

用于为类型创建别名,增强代码可读性。

type StringOrNumber = string | number;

type Callback = (data: string) => void;

其他高级特性

索引类型

用于动态访问对象属性。

function getProperty<T, K extends keyof T>(obj: T, key: K) {
    return obj[key];
}

const user = { name: "Alice", age: 25 };
console.log(getProperty(user, "name")); // "Alice"

映射类型

用于基于现有类型创建新类型。

type Readonly<T> = {
    readonly [P in keyof T]: T[P];
};

type User = { name: string; age: number };
type ReadonlyUser = Readonly<User>;

条件类型

根据条件选择类型。

type IsString<T> = T extends string ? true : false;
type A = IsString<"hello">; // true
type B = IsString<123>;     // false

函数

  1. 函数声明与类型注解
function add(a: number, b: number): number {
  return a + b;
}
  1. 可选参数与默认参数
function greet(name: string, greeting: string = "Hello"): string {
  return `${greeting}, ${name}!`;
}
  1. 剩余参数
function sum(...numbers: number[]): number {
  return numbers.reduce((acc, curr) => acc + curr, 0);
}
  1. 函数重载
function combine(a: string, b: string): string;
function combine(a: number, b: number): number;
function combine(a: any, b: any): any {
  return a + b;
}

接口

基本概念

  • 接口定义:接口通过 interface 关键字定义,描述对象的属性和方法。
  • 接口实现:对象可以通过实现接口来满足接口定义的契约。
  • 接口扩展:接口可以继承其他接口,形成更复杂的结构。

基本用法

  1. 声明接口
interface User {
  id: number;               // 必填属性
  name: string;             // 必填属性
  age?: number;             // 可选属性
  readonly email: string;   // 只读属性
}
  1. 使用接口
const user: User = {
  id: 1,
  name: "Alice",
  email: "alice@example.com"
};

user.name = "Bob";              // ✅ 允许修改
user.email = "bob@example.com"; // ❌ 编译错误:Cannot assign to 'email' because it is a read-only property.

接口扩展

接口可以使用 extend 关键字继承其他接口。

interface Person {
  name: string;
  age: number;
}

interface Employee extends Person {
  employeeId: number;
  department: string;
}

const employee: Employee = {
  name: "Alice",
  age: 25,
  employeeId: 123,
  department: "Engineering"
};

接口与函数

  1. 定义函数接口
interface SearchFunc {
  (source: string, subString: string): boolean;
}
  1. 实现接口
const mySearch: SearchFunc = function (source: string, subString: string): boolean {
  return source.includes(subString);
};

console.log(mySearch("Hello, world!", "world")); // true

接口与类

  1. 定义类接口
interface ClockInterface {
  currentTime: Date;
  setTime(d: Date): void;
}
  1. 实现接口
class Clock implements ClockInterface {
  currentTime: Date = new Date();

  setTime(d: Date): void {
    this.currentTime = d;
  }
}

const clock = new Clock();
clock.setTime(new Date(2023, 10, 1));
console.log(clock.currentTime); // 2023-10-01T00:00:00.000Z

接口与索引签名

  1. 定义索引签名
interface StringArray {
  [index: number]: string;
}

const myArray: StringArray = ["Alice", "Bob"];
console.log(myArray[0]); // "Alice"
  1. 混合索引签名
interface UserDictionary {
  [key: string]: string | number;
  name: string; // 必须符合索引签名的类型
  age: number;
}

const user: UserDictionary = {
  name: "Alice",
  age: 25,
  email: "alice@example.com" // 动态属性
};

接口与泛型

  1. 定义泛型接口
interface KeyValuePair<K, V> {
  key: K;
  value: V;
}
  1. 实现接口
const pair1: KeyValuePair<string, number> = { key: "age", value: 25 };
const pair2: KeyValuePair<number, string> = { key: 1, value: "Alice" };

接口与类型别名

接口和类型别名(type)都可以用来描述对象结构,但它们有一些区别:

特性 接口 (interface) 类型别名 (type)
扩展 支持 extends 继承 不支持继承,但可以通过交叉类型扩展
合并 同名接口会自动合并 同名类型别名会报错
适用场景 描述对象结构、类实现 描述任意类型(联合类型、交叉类型等)

接口合并

interface User {
  name: string;
}

interface User {
  age: number;
}

const user: User = {
  name: "Alice",
  age: 25
};

类型别名扩展

type Person = {
  name: string;
};

type Employee = Person & {
  employeeId: number;
};

const employee: Employee = {
  name: "Alice",
  employeeId: 123
};

  1. 类的定义与实例化
class Animal {
  name: string;
  constructor(name: string) {
    this.name = name;
  }
}
  1. 构造函数与属性修饰符
class Animal {
  constructor(public name: string) {}
}
  1. 继承与多态
class Dog extends Animal {
  bark(): void {
    console.log("Woof!");
  }
}
  1. 抽象类与接口实现
abstract class Shape {
  abstract getArea(): number;
}

class Circle extends Shape {
  constructor(private radius: number) {
    super();
  }
  getArea(): number {
    return Math.PI * this.radius ** 2;
  }
}

泛型

  1. 泛型的基本概念
function identity<T>(arg: T): T {
  return arg;
}
  1. 泛型函数
function logAndReturn<T>(value: T): T {
  console.log(value);
  return value;
}
  1. 泛型接口
interface KeyValuePair<K, V> {
  key: K;
  value: V;
}
  1. 泛型约束
function getProperty<T, K extends keyof T>(obj: T, key: K) {
  return obj[key];
}

模块

  1. 模块的导入与导出
// math.ts
export function add(a: number, b: number): number {
  return a + b;
}

// main.ts
import { add } from "./math";
  1. 默认导出与命名导出
// math.ts
export default function add(a: number, b: number): number {
  return a + b;
}

// main.ts
import add from "./math";
  1. 命名空间的使用
namespace MathUtils {
  export function add(a: number, b: number): number {
    return a + b;
  }
}

编译器

编译过程监控

tsc --extendedDiagnostics  # 显示完整编译统计
tsc --generateTrace ./trace # 生成编译追踪数据

引用

  1. TypeScript官方文档
    https://www.typescriptlang.org/docs/handbook/intro.html

声明

内容准确性: 我会尽力确保所分享信息的准确性和可靠性,但由于个人知识有限,难免会有疏漏或错误。如果您在阅读过程中发现任何问题,请不吝赐教,我将及时更正。

AI: 文章部分代码参考了DeepSeek和ChatGTP大语言模型生成的内容。

posted on 2025-03-04 15:14  wubing7755  阅读(63)  评论(0)    收藏  举报