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.json的typeRoots和include包含.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);