实用指南:TypeScript知识总结


一、简介

  1. TypeScript 由微软开发,是基于 JavaScript 的一个扩展语言
  2. TypeScript 包含了JavaScript 的所有内容,即:TypeScriptJavaScript超集
  3. Typescript 增加了:静态类型检查、接口、泛型等很多现代开发特性,因此更适合大型项目的开发
  4. TypeScript 需要编译JavaScript ,然后交给浏览器或其他 JavaScript 运行环境执行

二、为什么需要TypeScript?

JavaScript 当年诞生时的定位是浏览器脚本语言,用于在网页中嵌入一些简单的逻辑,而且代码量很少。

随着时间的推移,JavaScript变得越来越流行,如今的 JavaScript 已经可以全栈编程了。

现如今的 JavaScript 应用场景比当年丰富的多,代码量也比当年大很多,随便一个JavaScript 项目的代码量,可以轻松的达到几万行,甚至十几万行!

然而 JavaScript 当年“出生简陋”没考虑到如今的应用场景和代码量,逐渐的就出现了很多困扰

JS的困扰

1.1. 不清不楚的数据类型

imgimg

1.2. 有漏洞的逻辑

else if{}中的语句永远不会执行,但是js不会报错

img

img

1.3. 访问不存在的属性

img

img

1.4. 拼写错误

img

img

静态类型检查

  1. 在代码运行前进行检查,发现代码的错误或不合理之处,减小运行时异常的出现的几率,,此种检查叫『静态类型检查』,TypeScript 的核心就是『静态类型检查』,简言之就是把运行时的错误前置(比如同样的错误代码,js只有在运行时才会报错,但是ts在写代码的时候就会报错)。
  2. 同样的功能,TypeScript的代码量要大于JavaScript,但由于 TypeScript 的代码结构更加清晰,在后期代码的维护中 TypeScript 却远胜于 JavaScript。

TS与JS的区别

TypeScriptJavaScript
JavaScript 的超集用于解决大型项目的代码复杂性一种脚本语言,用于创建动态网页
可以在编译期间发现并纠正错误作为一种解释型语言,只能在运行时发现错误
强类型,支持静态和动态类型弱类型,没有静态类型选项
最终被编译成 JavaScript 代码,使浏览器可以理解可以直接在浏览器中使用
支持模块、泛型和接口不支持模块,泛型或接口
社区的支持仍在增长,而且还不是很大大量的社区支持以及大量文档和解决问题的支持

三、编译TypeScript

浏览器不能直接运行TypeScript代码,需要编译为Javacript代码

1. 命令行编译(几乎不用)

要把.ts文件编译为.js文件,需要配置TypeScript的编译环境,步骤如下

  1. 成功创建一个demo.ts文件
const person = {
name: '李四',
age: 18,
}
console.log(`我叫${ person.name },我今年${ person.age }岁了`)
  1. 安装全局TypeScript
npm i typescript -g
  1. 使用命令编译.ts文件
tsc demo.ts

2. 自动化编译

  1. 创建TypeScript编译控制文件:tsconfig.json
tsc --init
  1. 监视目录中所有.ts文件的变化
tsc --watch
  1. 小优化:希望当编译出错时不生成.js文件
"compilerOptions": {
"noEmitOnError": true,
}
{
// 这个文件是ts编译器的配置文件,ts编译器可以根据他的信息来对代码进行编译
//"include":用来指定哪些ts文件需要被编译
//路径:**表示任意目录
//      *表示任意文件
//"exclude”:用来指定哪些文件不需要被编译
//默认值:["node_modules","bower_components","jspm_packages"]
// "include": [
//     "src/**/*"
// ],
// "exclude": [
//     "node_modules"
// ]
//编译器的选项
"compilerOptions": {
//指定ts被编译为js的版本
"target": "es2015",//ES6
//指定js的模块化规范
"module": "es2015",
//用来指定编译后的文件所放的目录
"outDir": "./dist",
//将代码合并为一个文件,设置outFile后,
// 所有的全局作用域中的代码会合并到同一个文件中
"outFile": "./dist/bundle.js",
//是否对js文件进行编译,默认是false
"allowJs": true,
//是否检查js代码是否符合语法规范,默认是false
"checkJs": true,
//是否移除注释
"removeComments": true,
//不生成编译后的文件
"noEmit": true,
//当有错误时不生成编译后的文件
"noEmitOnError": true,
//设置编译后的js文件是否使用严格模式,默认false
//所有严格检查的开关(设置了这个后后面四个就不用写了)
"strict": true,
"alwaysStrict": true,
//不允许隐式的any类型
"noImplicitAny": true,
//不允许不明确类型的this
"noImplicitThis": true,
//严格检查空值
"strictNullChecks": true,
}
}

四、类型声明

  1. 类型声明是TS非常重要的一个特点
  2. 通过类型声明可以指定TS中的变量(参数,形参)的类型
  3. 指定类型后,当为变量赋值时,TS编译器会自动检查值是否符合类型声明,符合则赋值,否则报错
  4. 类型声明给变量设置了类型,使得变量者能存储某种类型的值
  5. 语法:
//声明一个变量,同时指定为Number类型
let a: number;
a = 10;
//下面这行会报错:不能将类型“string”分配给类型“number”。
//但是即使报错也会编译成功(编译成js)
// a="333";
//声明变量的同时进行赋值(会自动进行类型检测)
let c = false;
c = true;
//参数要指定类型,返回值也要指定类型
function test(a: number, b: number) {
return a + b;
}
//可以直接使用字面量进行类型声明
let d: 10;
//报错:不能将类型“11”分配给类型“10”。
// d=11;
//可以使用|来连接多个类型(联合类型)
let e: "male" | "female";
e = "male";
e = "female";
let f: number | string;
f = 10;
f = "10";

五、类型判断

  1. TS拥有自动类型判断机制
  2. 当对变量的声明和赋值同时进行时,TS编译器会自动判断变量的类型
let d=-99;//TypeScript会自动推算出d的类型是number
d=false;会报错
  1. 如果变量的声明和赋值时同时进行的,可以忽略掉类型声明

六、类型总览

img

JavaScript中的数据类型
  1. string
  2. number
  3. boolean
  4. object
  5. null
  6. undefined
  7. bigint
  8. symbol

备注:其中object包括Array,Function,Date,Error…

TypeScript中的数据类型
  1. 上述所有JS类型

  2. 六个新类型
    any
    unknow
    never
    void
    tuple
    enum

  3. 两个用于自定义类型的方式
    type
    enterface

注意:

在 JavaScript 中的这些内置构造函数:Number,String、Boolean他们用于创建对应的包装对象,在日常开发是很少用到,在TypeScript中也是同理,所以在TypeScript中进行类型声明时,通常都是用小写的 numbe,string,boolean

类型的大写和小写是有区别的,String和string不一样

let str1: string://TS官方推荐的写法str1 ='hello'
str1 = new String('hello');
let str2: String;
str2 = 'hello';
str2 = new String('hello');
console.log(typeof str1);
console.log(typeof str2);

在这里插入图片描述

  1. 原始类型和包装对象
  • 原始类型:如number,string,boolean,在JavaScript中是最简单的数据类型,他们在内存中占用的空间少,处理速度快
  • 包装对象:如Number对象,String对象,Boolean对象,是复杂类型,在内存中占用更多空间,在日常开发中很少有开发人员自己创建包装对象
  1. 自动装箱:JavaScript在必要时会自动降原始类型包装成对象,以便调用方法和属性
    在这里插入图片描述

七、常用类型

1. any

any:任意类型,一个变量设置为any类型后,相当于对该变量关闭了ts的类型检测

//显式any
let g: any;
//隐式any:没有明确类型的变量
let h;
g = 10;
g = "10";
g = true;

any类型的变量,可以复制给任意类型的变量

let s: string;
//将any类型的值赋值给一个字符串时,不报错
//但是会把两者的类型检查都给关了(将一个true赋值给一个字符串类型的变量)
s = g;

2. unknown

unknown:未知类型

  1. unknown可以理解为一个类型安全的any,适用于:不确定数据的具体类型
let i: unknown;
i = 10;
i = true;
i = "10";
//将unknown类型的值赋值给一个字符串时,报错:不能将类型“unknown”分配给类型“string”。
s=i;
  1. unknown会强制开发者在使用之前进行类型检查,从而提供更强的类型安全性
//解决办法一:判断一下类型
if (typeof i === 'string') {
s = i;
}
//解决办法二:类型断言
//告诉编译器变量的实际类型
s = i as string;
//解决办法三:
s = <string>i;
  1. 读取any类型数据的任何属性都不会报错,而unknown正好与之相饭
let str1: string
str1 = 'hello'
str1.toUpperCase()//无警告
let str2: any
str2 ='hello'
str2.toUppercase()//无警告
str2.qwe
str2.asd
str2.xyz
let str3: unknown
str3 = 'hello';
str3.toUpperCase();//警告:“str3”的类型为“未知”
str3.qwe();//警告:“str3”的类型为“未知”
//解决:
(str3 as string).toUpperCase()

3. never

never:任何值都不是,简而言之就是不能有值,undefined,null,…都不行

  1. 几乎不用never去直接限制变量,因为没有意义
let a:never;
//已下对a的所有赋值都会有警告
a=1;
a=true;
a=undefined;
  1. never一般是TypeScript主动推断出来的
//指定a的类型为string
let a: string
// 给a设置一个值
a = 'hello'
if (typeof a === 'string') {
console.log(a.toUpperCase())
} else {
console.log(a)//Typescript会推断出此处的a是never,因为没有任何一个值符合此处的逻辑
}

img

  1. never也可以用来限制函数的返回值类型
//限制这个函数不需要有任何返回值
function demo(): never {
throw new Error('程序运行异常!')
}
let x = demo();
console.log(x)

img

4. void

  1. void通常用于函数返回值声明,含义:函数不返回任何值,调用者也不应依赖其返回值进行操作
function logMessage(msg:string):void{
console.log(msg);
}
logMessage('你好');

注意:

​ 编码者没有编写 return 去指定函数的返回值,所以 logMessage 函数是没有显式返回值的,但会有一个隐式返回值,就是 undefined ;即:虽然函数返回类型为 void,但也是可以接受 undefined

简单记:undefinedvoid可以接受的一种“空”

  1. 以下写法符合规范
// 无警告
function logMessagel(msg: string): void {
console.log(msg)
}
// 无警告
function logMessage2(msg: string): void {
console.log(msg)
return;
}
// 无警告
function logMessage3(msg: string): void {
console.log(msg);
return undefined
}
  1. 返回值是void和undefined还是有区别的
function demo1(): void {
console.log("@")
}
let result1 = demo1()
if (result1) {//报错:无法测试 "void" 类型的表达式的真实性。
}
function demo2(): undefined {
console.log("@")
}
let result2 = demo2()
if (result2) {
}

理解 void 与 undefined

  1. void是一个广泛的概念,用来表达“空”,而“undefined”则是这种“空”的表现形式之一,因此可以说 undefinedvoid 能接受的“空”状态的一种具体形式。
  2. 换句话说: void 包含 undefined ,但 void 表达的语义超越了单纯的 undefined,它是一种意图上的约定,而不仅仅是特定值的限制。

总结:若函数返回类型为 void ,那么:

  1. 从语法上讲:函数是可以返回 undefined 的,至于显式返回,还是隐式返回,这无所谓!
  2. 从语义上讲:函数调用者不应关心函数返回的值,也不应依赖返回值进行任何操作!即使返回了 undefined 值。

5. object

关于objectObject,实际开发中用的相对较少,因为范围太大了

5.1.1. object

可以存储所有非原始类型,对象,函数,数组等,由于限制的范围比较宽泛,在实际开发中使用的相对较少

img

5.1.2. Object
  • 可以存储:所以可以调用Object方法的类型
  • 不可以存储:undefinednull

由于限制的范围实在太大,用的不多

img

5.1.3. 声明对象类型
  1. 实际开发中,声明对象的形式
//限制person对象必须有name属性,age可选
let person1: { name: string, age?: number };
//可以用分号分隔
let person2: { name: string;age?: number };
//可以用换行符做分隔
let person3: {
name: string
age?: number
};
person1 = { name: '张三', age: 18 }
person2 = { name: '张三' }
//报错:对象字面量只能指定已知属性,并且“gender”不在类型“{ name: string; age?: number; }”中
person3 = { name: '张三', age: 18, gender: '男' }
  1. 索引签名:允许定义对象可以具有任意数量的属性,这些属性的键和类型是可变的,适用于具有动态属性的对象
let person1: { name: string, age?: number,[key:string]:any };
person3 = { name: '张三', age: 18, gender: '男' }//不报错
5.1.4. 声明函数类型

img

备注:

  1. TypeScript中的=>在函数类型声明时表示函数类型,描述其参数类型和返回值类型
  2. JavaScript中的=>是一种定义函数的语法,是具体的函数实现
  3. 函数类型声明还可以使用:接口,自定义类型等方式
5.1.5. 声明数组类型
//声明数组
let arr1:string[]
let arr2:Array<number>
  arr1 = ['1', '2', '3']
  arr2 = [1, 2, 3]
  console.log(arr1, arr2)

img

6. tuple

​ 元组(tuple)是一种特殊的数组类型,可以存储固定数量的元素,并且每个元素的类型是已知的可以不同。元组用于精确描述一组值的类型,?表示可选元素。

//第一个元素必须是string类型,第二个元素必须是number类型。
let arr1:[string,number]
/第一个元素必须是number类型,第二个元素是可选的,如果存在,必须是boolean类型。
let arr2:[number,boolean?]
//第一个元素必须是number类型,后面的元素可以是任意数量的string类型
1et arr3:[number,...string[]]
//可以赋值
arr1=['he11o',123]
arr2=[100,false]
arr2=[200]
arr3=[100,'he11o','wor1d']
arr3=[100]
//不可以赋值,arr1声明时是两个元素,赋值的是三个
arr1=['hello',123,false]

7. enum

定义:枚举 enum 可以定义一组命名常量, 它能增强代码的可读性,也让代码更好维护

如下代码的功能是:根据调用walk时传入的不同参数,执行不同的逻辑,存在的问题是调用walk时传参时没
有任何提示,编码者很容易写错字符串内容;并且用于判断逻辑的up,down, left,right连续且相关的一组值,那此时就特别适合使用

function walk(str: string) {
if (str === 'up') {
console.log("向【上】走");
} else if (str === 'down') {
console.log("向【下】走");
} else if (str === 'left'){
console.log("向【左】走");
} else if (str === 'right') {
console.log("向【右】走");
} else {
console.log("未知方向")
}
}
walk('up')
walk('down')
walk("left")
walk("right")
  1. 数字枚举

数字枚举是一种最常见的枚举类型,其成员的值会自动递增,且数字枚举还具备反向映射的特点,下面戴那种,可以发现:可以通过值来获取对应枚举成员的名称

enum Direction {
Up,
Down,
Left ,
Right
}
console.log(Direction);
//反向映射
console.log(Direction.Up);
console.log(Direction[0]);
//这行代码报错,因为枚举中的属性是只读的,不可修改
Direction.Up="shang";

img
也可以指定枚举成员的初始值,气候的成员只会自动递增

enum Direction {
Up=6,
Down,
Left ,
Right
}
console.log(Direction.Up);//6
console.log(Direction.Down);//7

使用数字枚举完成walk函数中的逻辑,会发现:代码更加直观易读,类型安全,易于维护

enum Direction {
up,
down,
left,
right
}
function walk(n: Direction) {
if (n === Direction.up) {
console.log("向【上】走");
} else if (n === Direction.down) {
console.log("向下走");
} else if (n === Direction.left) {
console.log("向【左】走");
} else if (n === Direction.right) {
console.log("向l右】走");
} else {
console.log("未知方向");
}
}
walk(Direction.up)
walk(Direction.down)
  1. 字符串枚举

丢失了反向映射 ,枚举成员是字符串类型

enum Direction {
Up = 'up',
Down = 'down',
Left = 'left',
Right = 'right'
}
console.log(Direction)

img

  1. 常量枚举

常量枚举是一种特殊的枚举类型,他使用const关键字定义,在编译时会被内联,避免生成一些额外的代码

编译内联:

“内联”就是TypeScript在编译时,会见枚举成员引用替换为他们实际的值,而不是生成额外的枚举对象,这可以减少生成的JS 代码,提高运行时性能

使用普通枚举:

enum Direction {
Up,
Down,
Left ,
Right
}
let x=Direction.Up;

编译后生成的js

var Direction;
(function (Direction) {
Direction[Direction["Up"] = 0] = "Up";
Direction[Direction["Down"] = 1] = "Down";
Direction[Direction["Left"] = 2] = "Left";
Direction[Direction["Right"] = 3] = "Right";
})(Direction || (Direction = {}));
let x = Direction.Up;
export {};
//# sourceMappingURL=Demo.js.map

使用常量枚举:

const enum Direction {
Up,
Down,
Left ,
Right
}
let x=Direction.Up;

编译后(在 "preserveConstEnums": false的前提下)

let x = 0 /* Direction.Up */;
export {};
//# sourceMappingURL=Demo.js.map

8. type

type 可以为任意类型创建别名,让代码更简洁,可读性更强,同时能更方便的进行类型服用和扩展

  1. 基本用法

类型别名使用type关键字定义,type后跟类型名称,例如下面代码中num是类型别名

type num=number;
let price:num;
price=100;
  1. 联合类型(或)

联合类型是一种高级类型,它表示一个值可以是几种不同类型之一

type Status =number|string
type Gender ='男'|'女'
function printstatus(data:Status):void{
console.log(data)
}
function printGender(data:Gender):void{
console.log(data)
}
printstatus(404)
printstatus('404')
printGender('男')
printGender('女')
  1. 交叉类型(并且)
type Area = {
height: number;
width: number;
}
type Address = {
num: number
cell: number
room: string
}
type House = Area & Address;
const house: House = {
height: 100,
width: 100,
num: 3,
cell: 3,
room: '241'
}
type Demo=number&string;
let demo:Demo;//这一行TS会自动推断出demo的类型是never

9. 特殊情况

  1. 在定义函数时,限制函数返回值为void,那么函数的返回值就必须是空
function demo():void{
return undefined;
//以下返回值均不合法
// return 100;
// return true;
// return null;
// return [];
}
  1. 使用类型声明限制函数的返回值为void时,**TypeScript**并不会严格要求函数返回为空
type LogFunc=()=>void
//明明定义了返回值类型时void,但是代码中返回了100,却没有报错
const f1:LogFunc=()=>{
return 100;
}
const f2:LogFunc=()=>200;
const f3:LogFunc=function(){
return 300;
}

img

  1. 为什么?
const src=[1,2,3]
const dst=[0]
//完整写法
//这样写的返回值为undefined,符合函数定义时规定返回值为void
src.forEach((el)=>{
dst.push(el)
})
//箭头函数的形式
//写成箭头函数,默认dst.push(el)的返回值就是函数的返回值(返回一个数字)
//但是这个forEach函数定义时又被指明返回值为void,所以如果做严格的限制,就会报错
//不做限制,是为了让这种箭头函数写法可用
src.forEach((el)=>dst.push(el))

**void**作为函数返回值类型时,TypeScript 仅要求 “调用者不依赖该返回值”,也就是该返回值不可以拿来做任何事情,而不强制 “函数必须返回**undefined**

  1. 为什么 TypeScript 会这样设计?

这是为了灵活性。很多场景下,函数可能 “顺便” 返回了值,但调用者并不关心(比如 forEach 只需要执行回调的副作用,不处理返回值)。如果严格限制 void 必须返回 undefined,会导致很多合法用法报错(比如你例子中简化的箭头函数 (el) => dst.push(el))。

10. 属性修饰符

修饰符含义规则
public公开的可以被:类内部子类类外部访问
protected受保护的可以被:类内部子类访问
private私有的可以被:类内部访问
readonly只读属性属性无法修改

11. 抽象类

  1. 概述:抽象类是一种无法被实例化(不可以使用new关键字创建)的类,专门用来定义类的结构和行为;类中可以写抽象方法,也可以写具体实现。抽象类主要用来为其派生类提供一个基础结构,要求其派生类必须实现其中的抽象方法
  2. 简记:抽象类不能实例化,其意义是可以被继承;抽象类里可以有普通方法,也可以有抽象方法。通过以下场景,理解抽象类。

我们定义一个抽象类 Package,表示所有包裹的基本结构。任何包裹都有重量属性 weight,包裹都需要计算运费。但不同类型的包裹(如标准速度、特快专递)都有不同的运费计算方式,因此用于计算运费的 calculate方法是一个抽象方法,必须由子类来实现

abstract class Package {
//构造方法
constructor(public weight: number) { }
//抽象方法
abstract calculate(): number
//具体方法
print() {
console.log(`包裹的重量为${this.weight}`)
}
}

NormalPackage类继承了Package,实现了calculate方法

class NormalPackage extends Package {
constructor(
weight: number,
public unitPrice: number
) { super(weight) }
calculate(): number {
return this.weight * this.unitPrice
}
}

ExpressPackage类继承了Package,实现了calculate方法

class ExpressPackage extends Package {
constructor(
weight: number,
public unitPrice: number,
public expressFee: number
) { super(weight) }
calculate(): number {
if (this.weight > 10) {
return 10 * this.unitPrice + (this.weight - 10) * this.expressFee
} else {
return this.weight * this.unitPrice
}
}
}

总结:何时使用抽象类?

  1. 定义通用接口,为一组相关的类定义通用的行为(方法或属性)时
  2. 提供基础实现:在抽象类中提供某些方法或为其提供基础实现,这样派生类就可以继承并实现
  3. 确保关键实现:强制派生类实现一些关键性为
  4. 共享代码和逻辑:当多个类需要共享代码和逻辑时,抽象类可以避免代码重复

12. 接口

12.1. 定义类结构

interface PersonInterface{
name:string
age:number
speak(n:number):void
}
class Person implements PersonInterface{
constructor(
public name:string,
public age:number
){}
speak(n:number):void{
for(let i=0;i<n;i++){
console.log(`你好,我叫${this.name},今年${this.age}岁}`)
}
}
}
const p1=new Person('张三',18)
p1.speak(4)

12.2. 定义对象结构

interface UserInterface{
name:string
readonly gender:string//只读
age?:number
run:(n:number)=>void
}
const a:number=1
//这个接口当类型使用了
const user:UserInterface={
name:"张三",
gender:"男",
run:(n:number)=>{
console.log(`${n}km/h`)
}
}

12.3. 定义函数结构

interface CountInterface{
(a:number,b:number):number;
}
const count:CountInterface=(x,y)=>{
return x+y
}

12.4. 接口的合并(可重复定义)

interface PersonInterface {
name: string
age: number
}
interface PersonInterface {
gender:string
}
const p:PersonInterface={
name:'tom',
age:18,
gender:'女'
}

总结:何时使用接口?

  1. 定义对象的格式:描述数据模型,API相应格式,配置对象…是开发中用的最多的场景
  2. 类的契约:规定一个类需要实现哪些属性和方法
  3. 自动合并:一般用于扩展第三方库的类型,这种特性在大型项目中可能会用到

13. interface和type的区别

相同点interfacetype都可以用来定义对象结构,两者在许多场景中是可以互换的

不同点:

interface:更专注于定义对象和类的结构,支持继承,合并

type:可以定义类型别名,联合类型,交叉类型,但不支持继承和自动合并

14. interface和抽象类的区别

相同点:都用来定义一个类的格式

不同点

​ 接口:只能描述结构,不能有任何代码实现,一个类可以实现多个接口

​ 抽象类:既可以包含抽象方法,也可以包含具体方法,一个类只能继承一个抽象类

15. 泛型

泛型允许我们在定义函数,类或接口时,使用类型参数来表示为指定的类型,这些参数在具体使用时,才能被指定具体的类型,反省能让同一段代码适用于多种类型,同时仍然保持类型的安全性

下面的代码中就是泛型,不一定非叫T,设置泛型后可在函数中使用T来表示类型

//泛型函数
function logData<T>(data:T){
  console.log(data)
  }
  logData<number>(100)
    logData<string>('hello')
      //泛型可以有多个
      function logData<T, U>(data1: T, data2: U) {
        Date.now() % 2 ? console.log(data1) : console.log(data2)
        }
        logData<number, boolean>(100, true)
          logData<string, string>('hello', 'world')
            //泛型接口
            function logData<T, U>(data1: T, data2: U) {
              Date.now() % 2 ? console.log(data1) : console.log(data2)
              }
              logData<number, boolean>(100, true)
                logData<string, string>('hello', 'world')
                  //泛型类
                  class Person<T>{
                    constructor(
                    public name:string,
                    public age:number,
                    public extraInfo:T
                    ){}
                    speak(){
                    console.log(`${this.name} ${this.age} ${this.extraInfo}`)
                    }
                    }
                    const p1=new Person<number>('tom',18,100);
                      type JobInfo={
                      title:string;
                      company:string;
                      }
                      const p2=new Person<JobInfo>('tom',18,{title:'前端',company:'百度'});

八、类型声明文件

类型声明文件是TypeScript中的一种特殊文件,通常以..d.ts作为扩展名,它的主要作用是为现有的JavaScript代码提供类型信息,是的TypeScript能够在使用这些JavaScript库或模板时进行类型检查和提示

export function add(a,b){
return a+b;
}
export function mul(a,b){
return a*b;
}
declare function add(a:number,b:number):number;
declare function mul(a:number,b:number):number;
export{add.mul};

生活感悟

这周也是按照计划完成了TS的学习,但是感觉要将TS运用到项目中还是有点困难,毕竟写JS写习惯了。接下来就是复习基础知识,再找一些新的库看看

学习计划

感觉基础还是很不扎实,下周将JS高级和ES6复习一下,顺便看看uniapp,下个月就要开始写项目了,得重视起来

posted @ 2025-11-23 08:38  yangykaifa  阅读(19)  评论(0)    收藏  举报