TypeScript
TypeScript 由微软开发,是 JavaScript 的超集,浏览器暂不支持直接运行 TS,需编译为 JS 执行。
一、类型声明
1. 基础变量/常量声明
// 语法:let/const 标识符: 类型 = 赋值letstr:string="this is a string";// 变量constPI:number=3.14159;// 常量2. 函数及返回值声明
// 语法:function 函数名(参数1:类型, 参数2:类型): 返回值类型 {方法体}functioncount(a:number,b:number):number{returna+b;}3. 字面量类型
// 字面量类型限制变量只能赋值为指定字面量letb:"hello"="hello";// 正确声明方式// b = 1; // 报错:不能将类型“number”分配给类型“"hello"”二、核心数据类型
TS 包含 JS 全部数据类型,新增了更严格的类型约束和专属类型;
string/number/boolean:基础类型(小写)String/Number/Boolean:包装对象(大写,极少直接使用)
1. any(任意类型)
放弃类型检查,可赋值给任意类型变量
leta:any;// 显式声明anyletb;// 隐式推断为anya=false;a="str";letbo:boolean=a;// 不报错2. unknown(类型安全的any)
需类型校验/断言后才能赋值给其他类型
leta:unknown;a=99;a="this is str";// 方式1:类型判断letstr1:string;if(typeofa==="string"){str1=a;}// 方式2:类型断言(两种写法)letstr2:string=aasstring;letstr3:string=<string>a;3. never/void
never:表示永远不会有返回值(如抛出异常的函数)void:表示无返回值(更常用)
4. 对象类型
// 基础对象声明letperson:{name:string;age:number;};// 可选属性 + 任意属性letperson4:{name:string;age?:number;// 可选属性[key:string]:any;// 任意属性};person4={name:"tom",age:123,gender:"male"};// 合法5. 函数类型声明
letcount:(a:number,b:number)=>number;count=(x:number,y:number)=>{returnx+y;};6. 数组类型
letarr1:string[];// 方式1:基础写法letarr2:Array<number>;// 方式2:泛型写法arr1=["Hello","World"];arr2=[1,2,3,4,5];7. 元组(Tuple)
固定长度和类型的数组
letarr1:[string,number];// 长度2,类型依次为string、numberletarr2:[number,boolean];letarr3:[string,number,boolean,...string[]];// 扩展元组(前3个固定,后续为string)8. 枚举(Enum)
enumDirection{Up=01,Down=02,Left=03,Right=04}// 枚举访问console.log(Direction.Right);// 4console.log(Direction[0x04]);// "Right"// 枚举使用示例functionwalk(dir:Direction){switch(dir){caseDirection.Up:console.log("向上移动");break;caseDirection.Down:console.log("向下移动");break;}}walk(Direction.Down);// 输出:向下移动三、类型组合
1. 联合类型(或 |)
变量可以是多个类型中的一种
letnumOrStr:number|string;numOrStr=123;numOrStr="abc";2. 交叉类型(且 &)
组合多个类型的属性
typeName={name:string};typeAge={age:number};typePerson=Name&Age;// 同时包含name和ageletp:Person={name:"张三",age:20};四、类(Class)
1. 基础类与继承
classPerson{name:string;age:number;constructor(name:string,age:number){this.name=name;this.age=age;}speak():void{console.log(`姓名:${this.name},年龄:${this.age}`);}}classStudentextendsPerson{publicgrade:string;// 公共属性(默认public)privatesex:string="boy";// 私有属性(仅类内部访问)readonlyidCard:string;// 只读属性(仅声明/构造函数初始化)constructor(name:string,age:number,grade:string,idCard?:string){super(name,age);// 必须调用父类构造函数this.grade=grade;this.idCard=idCard||"0000000000";// 只读属性可在构造函数赋值}// 重写父类方法(需加override)overridespeak():void{super.speak();// 调用父类方法console.log(`年级:${this.grade}`);}privateshowSex(){console.log(this.sex);// 私有方法仅内部调用}}2. 访问修饰符
public:公共(默认),任意位置访问private:私有,仅类内部访问protected:受保护,类内部 + 子类访问readonly:只读,仅声明/构造函数初始化
3. 抽象类
包含抽象方法(无实现),只能被继承,不能实例化
abstractclassPackage{publicweight:number;publicunitPrice:number=0.5;constructor(weight:number,unitPrice?:number){this.weight=weight;if(unitPrice)this.unitPrice=unitPrice;}// 抽象方法(子类必须实现)abstractcalculate():number;// 普通方法publicgetWeight():number{returnthis.weight;}}// 子类实现抽象方法classStandardPackageextendsPackage{calculate():number{returnthis.weight*this.unitPrice;}}constpack=newStandardPackage(10,2);console.log(pack.calculate());// 20五、泛型
复用性强的类型约束,支持任意类型的类型安全
// 1. 泛型函数functionlogData<T>(data:T):void{console.log(data);}logData<string>("hello");// 指定类型logData(123);// 自动推断number// 2. 多泛型参数functionlogData2<T,X>(data1:T,data2:X):void{console.log(`${data1},${data2}`);}// 3. 泛型接口interfaceIPerson<T>{name:string;age:number;extraInfo:T;// 动态类型}// 4. 泛型类classStudent<T>{constructor(publicname:string,publicage:number,publicextraInfo:T){}}// 使用示例typeJobInfo={title:string;company:string};letp: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 文件只声明类型,不写具体实现
// 示例:src/types/user.d.ts(自定义类型文件)// 1. 声明基础类型typeUserId=string|number;// 2. 声明接口interfaceUser{id:UserId;name:string;age?:number;isAdmin:boolean;}// 3. 声明函数类型declarefunctiongetUserById(id:UserId):User|null;// 4. 声明模块(为无类型的 JS 模块补充类型)declaremodule'my-custom-js-lib'{exportfunctionsayHello(name:string):void;exportconstversion:string;}2. 在 TS 代码中使用 .d.ts 中的类型
无需手动 import,TypeScript 会自动扫描项目中的 .d.ts 文件(需确保 tsconfig.json 配置正确):
// 示例:src/index.ts// 直接使用 user.d.ts 中声明的类型constuser:User={id:1001,name:'张三',isAdmin:false};// 使用声明的函数类型constgetUser:typeofgetUserById=(id)=>{returnid===1001?user:null;};// 使用声明的模块import{sayHello,version}from'my-custom-js-lib';sayHello(user.name);// 类型提示:参数必须是 stringconsole.log(version);// 类型提示:version 是 string3. 为本地 JS 文件补充类型(实战场景)
有一个 JS 文件 src/utils/format.js,没有类型定义:
// src/utils/format.jsexportfunctionformatDate(date){returndate.toLocaleDateString();}创建对应的 .d.ts 文件补充类型:
// src/utils/format.d.tsdeclaremodule'./format.js'{exportfunctionformatDate(date:Date):string;}然后在 TS 中使用:
import{formatDate}from'./utils/format.js';// 类型校验:参数必须是 Date 类型,返回值是 stringconsttoday=formatDate(newDate());console.log(today);