TypeScript 学习_类型与语法(2)

TypeScript

TypeScript 由微软开发,是 JavaScript 的超集,浏览器暂不支持直接运行 TS,需编译为 JS 执行。

一、类型声明

1. 基础变量/常量声明

typescript 复制代码
// 语法:let/const 标识符: 类型 = 赋值
let str: string = "this is a string"; // 变量
const PI: number = 3.14159; // 常量

2. 函数及返回值声明

typescript 复制代码
// 语法:function 函数名(参数1:类型, 参数2:类型): 返回值类型 {方法体}
function count(a: number, b: number): number {
    return a + b;
}

3. 字面量类型

typescript 复制代码
// 字面量类型限制变量只能赋值为指定字面量
let b: "hello" = "hello"; // 正确声明方式
// b = 1; // 报错:不能将类型"number"分配给类型""hello""

二、核心数据类型

TS 包含 JS 全部数据类型,新增了更严格的类型约束和专属类型;

  • string/number/boolean:基础类型(小写)
  • String/Number/Boolean:包装对象(大写,极少直接使用)

1. any(任意类型)

放弃类型检查,可赋值给任意类型变量

typescript 复制代码
let a: any; // 显式声明any
let b; // 隐式推断为any

a = false;
a = "str";
let bo: boolean = a; // 不报错

2. unknown(类型安全的any)

需类型校验/断言后才能赋值给其他类型

typescript 复制代码
let a: unknown;
a = 99;
a = "this is str";

// 方式1:类型判断
let str1: string;
if (typeof a === "string") {
    str1 = a;
}

// 方式2:类型断言(两种写法)
let str2: string = a as string;
let str3: string = <string>a;

3. never/void

  • never:表示永远不会有返回值(如抛出异常的函数)
  • void:表示无返回值(更常用)

4. 对象类型

typescript 复制代码
// 基础对象声明
let person: {
    name: string;
    age: number;
};

// 可选属性 + 任意属性
let person4: {
    name: string;
    age?: number; // 可选属性
    [key: string]: any; // 任意属性
};
person4 = { name: "tom", age: 123, gender: "male" }; // 合法

5. 函数类型声明

typescript 复制代码
let count: (a: number, b: number) => number;
count = (x: number, y: number) => {
    return x + y;
};

6. 数组类型

typescript 复制代码
let arr1: string[]; // 方式1:基础写法
let arr2: Array<number>; // 方式2:泛型写法

arr1 = ["Hello", "World"];
arr2 = [1, 2, 3, 4, 5];

7. 元组(Tuple)

固定长度和类型的数组

typescript 复制代码
let arr1: [string, number]; // 长度2,类型依次为string、number
let arr2: [number, boolean];
let arr3: [string, number, boolean, ...string[]]; // 扩展元组(前3个固定,后续为string)

8. 枚举(Enum)

typescript 复制代码
enum Direction {
    Up = 01,
    Down = 02,
    Left = 03,
    Right = 04
}

// 枚举访问
console.log(Direction.Right); // 4
console.log(Direction[0x04]); // "Right"

// 枚举使用示例
function walk(dir: Direction) {
    switch (dir) {
        case Direction.Up:
            console.log("向上移动");
            break;
        case Direction.Down:
            console.log("向下移动");
            break;
    }
}
walk(Direction.Down); // 输出:向下移动

三、类型组合

1. 联合类型(或 |)

变量可以是多个类型中的一种

typescript 复制代码
let numOrStr: number | string;
numOrStr = 123;
numOrStr = "abc";

2. 交叉类型(且 &)

组合多个类型的属性

typescript 复制代码
type Name = { name: string };
type Age = { age: number };
type Person = Name & Age; // 同时包含name和age

let p: Person = { name: "张三", age: 20 };

四、类(Class)

1. 基础类与继承

typescript 复制代码
class Person {
    name: string;
    age: number;
    
    constructor(name: string, age: number) {
        this.name = name;
        this.age = age;
    }

    speak(): void {
        console.log(`姓名:${this.name},年龄:${this.age}`);
    }
}

class Student extends Person {
    public grade: string; // 公共属性(默认public)
    private sex: string = "boy"; // 私有属性(仅类内部访问)
    readonly idCard: string; // 只读属性(仅声明/构造函数初始化)

    constructor(name: string, age: number, grade: string, idCard?: string) {
        super(name, age); // 必须调用父类构造函数
        this.grade = grade;
        this.idCard = idCard || "0000000000"; // 只读属性可在构造函数赋值
    }

    // 重写父类方法(需加override)
    override speak(): void {
        super.speak(); // 调用父类方法
        console.log(`年级:${this.grade}`);
    }

    private showSex() {
        console.log(this.sex); // 私有方法仅内部调用
    }
}

2. 访问修饰符

  • public:公共(默认),任意位置访问
  • private:私有,仅类内部访问
  • protected:受保护,类内部 + 子类访问
  • readonly:只读,仅声明/构造函数初始化

3. 抽象类

包含抽象方法(无实现),只能被继承,不能实例化

typescript 复制代码
abstract class Package {
    public weight: number;
    public unitPrice: number = 0.5;

    constructor(weight: number, unitPrice?: number) {
        this.weight = weight;
        if (unitPrice) this.unitPrice = unitPrice;
    }

    // 抽象方法(子类必须实现)
    abstract calculate(): number;

    // 普通方法
    public getWeight(): number {
        return this.weight;
    }
}

// 子类实现抽象方法
class StandardPackage extends Package {
    calculate(): number {
        return this.weight * this.unitPrice;
    }
}

const pack = new StandardPackage(10, 2);
console.log(pack.calculate()); // 20

五、泛型

复用性强的类型约束,支持任意类型的类型安全

typescript 复制代码
// 1. 泛型函数
function logData<T>(data: T): void {
    console.log(data);
}
logData<string>("hello"); // 指定类型
logData(123); // 自动推断number

// 2. 多泛型参数
function logData2<T, X>(data1: T, data2: X): void {
    console.log(`${data1},${data2}`);
}

// 3. 泛型接口
interface IPerson<T> {
    name: string;
    age: number;
    extraInfo: T; // 动态类型
}

// 4. 泛型类
class Student<T> {
    constructor(
        public name: string,
        public age: number,
        public extraInfo: T
    ) {}
}

// 使用示例
type JobInfo = { title: string; company: string };
let p: IPerson<JobInfo> = {
    name: "张三",
    age: 20,
    extraInfo: { title: "工程师", company: "XX公司" }
};

六、类型文件

  • .d.ts:类型声明文件,用于声明类型(无具体实现)
  • @types/xxx:第三方库的类型声明包(如@types/node
  • @types/xxx 是社区提供的第三方库类型包,安装后直接用,无需额外配置;
  • .d.ts 是自定义类型声明文件,用于补充类型、复用类型,只声明不实现;
  • 关键配置:确保 tsconfig.jsontypeRootsinclude 包含 .d.ts 文件目录,TS 会自动识别。

1. 基础格式:.d.ts 文件只声明类型,不写具体实现

typescript 复制代码
// 示例:src/types/user.d.ts(自定义类型文件)
// 1. 声明基础类型
type UserId = string | number;

// 2. 声明接口
interface User {
  id: UserId;
  name: string;
  age?: number;
  isAdmin: boolean;
}

// 3. 声明函数类型
declare function getUserById(id: UserId): User | null;

// 4. 声明模块(为无类型的 JS 模块补充类型)
declare module 'my-custom-js-lib' {
  export function sayHello(name: string): void;
  export const version: string;
}

2. 在 TS 代码中使用 .d.ts 中的类型

无需手动 import,TypeScript 会自动扫描项目中的 .d.ts 文件(需确保 tsconfig.json 配置正确):

typescript 复制代码
// 示例:src/index.ts
// 直接使用 user.d.ts 中声明的类型
const user: User = {
  id: 1001,
  name: '张三',
  isAdmin: false
};

// 使用声明的函数类型
const getUser: typeof getUserById = (id) => {
  return id === 1001 ? user : null;
};

// 使用声明的模块
import { sayHello, version } from 'my-custom-js-lib';
sayHello(user.name); // 类型提示:参数必须是 string
console.log(version); // 类型提示:version 是 string

3. 为本地 JS 文件补充类型(实战场景)

有一个 JS 文件 src/utils/format.js,没有类型定义:

javascript 复制代码
// src/utils/format.js
export function formatDate(date) {
  return date.toLocaleDateString();
}

创建对应的 .d.ts 文件补充类型:

typescript 复制代码
// src/utils/format.d.ts
declare module './format.js' {
  export function formatDate(date: Date): string;
}

然后在 TS 中使用:

typescript 复制代码
import { formatDate } from './utils/format.js';

// 类型校验:参数必须是 Date 类型,返回值是 string
const today = formatDate(new Date());
console.log(today);
相关推荐
昨晚我输给了一辆AE864 小时前
为什么现在不推荐使用 React.FC 了?
前端·react.js·typescript
Wect10 小时前
LeetCode 130. 被围绕的区域:两种解法详解(BFS/DFS)
前端·算法·typescript
Dilettante25810 小时前
这一招让 Node 后端服务启动速度提升 75%!
typescript·node.js
jonjia1 天前
模块、脚本与声明文件
typescript
jonjia1 天前
配置 TypeScript
typescript
jonjia1 天前
TypeScript 工具函数开发
typescript
jonjia1 天前
注解与断言
typescript
jonjia1 天前
IDE 超能力
typescript
jonjia1 天前
对象类型
typescript
jonjia1 天前
快速搭建 TypeScript 开发环境
typescript