ts相关
文档相关
ts 教程
tsc CLI 文档
作用:将 ts 文件编译为 js 文件
shell
tsc ./Demo.ts
tsconfig.json
快速创建一个tsconfig.json文件
shell
ts --init
环境相关
查看 ts 版本
shell
tsc -v
快速创建一个 tsconfig.json 文件
shell
tsc init
让 node 能直接运行 ts 文件
在项目中
创建项目,安装依赖
pnpm add typescript ts-node @types/node -D
执行 ts 文件
pnpm exec tsc ./Demo.ts
在普通的文件夹中
shell
pnpm dlx ts-node ./Demo.ts
类型声明文件
.d.ts文件为类型声明文件
reference 引用
只可使用在 d.ts 文件中.
三斜线指令仅可放在包含它的文件的最顶端,不含注释,否则仅当注释处理
方法一:用路径声明依赖的
ts
/// <reference path="..." />
方法二:声明对某个包的依赖。
ts
/// <reference types="..." />
示例
表明这个文件使用了 @types/node/index.d.ts 里面声明的名字
ts
/// <reference types="node" />
declare 的用法
作用: 声明全局变量,全局函数,全局命名空间
使用场景: 对非 ts 模块,追加类型声明
示例
在开发 TypeScript 项目的过程中,你可能会通过 script 标签的形式来引入第三方 JS-SDK,比如引入微信公众平台的 JS-SDK。初始化之后,你就会在某个 TypeScript 文件中调用该 JS-SDK 提供的接口。 比如,调用拍照或从手机相册中选图接口来实现选图的功能:
ts
wx.chooseImage({
// Error:找不到名称“wx”。ts(2304)
count: 1, // 默认9
sizeType: ['original', 'compressed'],
sourceType: ['album', 'camera'],
success: function (res) {
var localIds = res.localIds
},
})
虽然你是按照微信开发文档来使用 JS-SDK 提供的接口,但对于以上的代码,TypeScript 编译器仍会提示相应的错误信息。这是因为 TypeScript 编译器不认识 wx 这个全局变量。
这时候可以使用 declare 关键字来声明 wx 全局变量,从而让 TypeScript 编译器能够识别该全局变量。
ts
declare namespace wx{
chooseImage(count:number,sizeType:string[],sourceType:string[],success:(ret:any)=>void)
}
interface 与 type 的区别
函数
不限定函数参数的个数传参
ts
function test(...args: number[]): void
剩余参数
ts
function test(name: string, age: number, ...restArgs: string[]): void
指定 this 类型
可推导 this 类型
ts
const info = {
name: '张三',
findName() {
console.log(this.name)
},
}
// 可以正常运行,typescript能正确推断this的类型
info.findName()
不确定的 this 类型
ts
function findName() {
console.log(this.name)
}
const info = {
name: '张三',
findName,
}
// 不能正常运行,ts无法确定this的类型
info.findName()
指定 this 类型
ts
type NameType = {
name: string
}
function findName(this: NameType) {
console.log(this.name)
}
const info = {
name: '张三',
findName,
}
// 正常运行,ts可以正常推断this的类型
info.findName()
箭头函数使用 this 报错
ts
console.log('hello')
/**
* 全局方法test
*
* @return {void} [return description]
*/
declare function test(): void
type fun = () => void
type InfoType = {
name: string
/**
* p.s. 这里的this:InfoType不是声明了一个参数,而是一个伪参数,用于告知ts当前this是InfoType这个类型。让ts能对如下调用方式进行报错ts(2684)
*
* const findName = info.findName
* findName()
*
* @param {InfoType} this [this description]
*
* @return {void} [return description]
*/
findName(this: InfoType): void
/**
* p.s. 这里的this:InfoType不是声明了一个参数,而是一个伪参数,用于告知ts当前this是InfoType这个类型。让ts能对如下调用方式进行报错ts(2684)
*
* const otherFindName = info.otherFindName
* otherFindName()
*
* @param {InfoType} this [this description]
*
* @return {void} [return description]
*/
otherFindName(this: InfoType): void
doFindName(this: InfoType): void
}
const info: InfoType = {
name: '张三',
/**
* 这是一个普通函数定义
*/
findName() {
console.log(this.name)
},
/**
* 这是一个普通函数定义
*
* p.s. 这里的this:InfoType不是声明了一个参数,而是告知ts当前this是InfoType这个类型。让ts能对如下调用方式进行报错ts(2684)
*
* const otherFindName = info.otherFindName
* otherFindName()
*/
otherFindName: function () {
console.log(this.name)
},
// 报错:箭头函数不能包含 "this" 参数。ts(2730)
doFindName: (this: InfoType) => {
/*
报错:
包含箭头函数捕获 "this" 的全局值。ts(7041)
类型“typeof globalThis”上不存在属性“name”。ts(2339)
*/
console.log(this.name)
},
}
const findName = info.findName
// findName()
info.findName()
const otherFindName = info.otherFindName
// 报错
otherFindName()
模块与命名空间
模块
TypeScript 与 ECMAScript 2015 一样,任何包含顶级 import 或者 export 的文件都被当成一个模块
相反地,如果一个文件不带有顶级的 import 或者 export 声明,那么它的内容被视为全局可见的
命名空间
作用就是解决重名问题
区别
命名空间是位于全局命名空间下的一个普通的带有名字的 JavaScript 对象。但很难去识别组件之间的依赖关系,尤其是在大型的应用中
像命名空间一样,模块可以包含代码和声明。 不同的是模块可以声明它的依赖
正常的 TS 项目开发过程中并不建议用命名空间,但通常在通过 d.ts 文件标记 js 库类型的时候使用命名空间,主要作用是给编译器编写代码的时候参考使用
参考资料
面试官:说说对 TypeScript 中命名空间与模块的理解?区别?