本次一共推出三篇文章,TS基础篇、TS高阶篇、TS习题篇,三篇文章均已发布。
语法篇
1. 联合类型的问题
interface a1{
kind:'circle' | 'square'
rad?:number
side?:number
}
function getAre(a:a1){
// return a.rad*3 //此处报错,因为 rad 为可选参数,可能未定义
return a.rad!*3 //加上 ! 解决该问题,表示类型推断排除null、undefined,
// 即只有类型推断不为null、undefined,我们才进行后面的步骤
}
// 上面虽然解决了这个问题,但是解决方法有点不太恰当,因为参数a可能是未传参数,
// 这在ts中虽然不会引起错误,但在js中可能会引起报错
// 最好的解决方法是分别定义数据类型
// 如下所示
// interface Circle {
// kind: 'circle'
// radius: number
// }
// interface Square {
// kind: 'square'
// sideLength: number
// }
// type Shape = Circle | Square
// function getArea(shape: Shape) {
// switch(shape.kind) {
// case 'circle':
// return Math.PI * shape.radius ** 2
// case 'square':
// return shape.sideLength ** 2
// }
// }
// TS中的!和?用法
// 1. 属性或参数中使用 ?:表示该属性或参数为可选项
// 2. 属性或参数中使用 !:表示强制解析(告诉typescript编译器,这里一定有值),常用于vue-decorator中的@Prop
// 3. 变量后使用 !:表示类型推断排除null、undefined
2. 类型守卫
所谓类型守卫,就是当一个变量或参数同时具有多种类型时,但我们只想针对于其中某一种类型进行运算
例如使用 typeof 来判断数据类型,即可实现在特定类型做特定运算
2.1. typeof 关键字
function print(str: number | string[] |null){
if(typeof str === 'string'){
// 当类型为 string 时进行相应运算
}else if(typeof str === 'object'){
// 当类型为 object 时进行相应运算
// 但此处要注意,null的类型也为object,如果想避免 null 可加上 && 运算符
// 即 (str && typeof str === 'object') 因为 null 在if判断后为false,故可直接写入
// 当然,如果不嫌麻烦 (str !== null && typeof str === 'object'),这样也是可以的
}else{
}
}
2.2. 真值缩小
// 我们需要知道,下面这些值在 if() 中,结果必定为false,反之为true
// {
// 0
// NaN
// "" (空字符串)
// 0n (bigint零的版本)
// null
// undefined
// }
function demo13(x: number | undefined){
if(!x){
return x
}else{
console.log(x+1)
}
}
demo13(3)
demo13(undefined)
// 上面,我们使用 !取反,如果为 undefined 就 return,否则输出x+1
2.3. 等值缩小
function demo14(x:string | number, y: string | boolean){
if(x===y){
// 此处的if判断很巧妙,因为两个参数身上都有共同的一个属性 string
// 所以只有当两者都为 string 类型时才有可能相等,故可以在此处调用 string 身上的方法
x.toUpperCase()
y.toLocaleLowerCase()
}
}
function demo15(x:null | number | undefined){
if(x != null){
console.log(x+1)
}
// 这里需要注意:我们虽然只做了 x != null 这一个判断,也就是说 x 还有可能为undefined
// 那为什么我们在下面进行加法运算,这里不会报错?这是因为我们用的是 != 即宽松的不等于判断,
// 这个宽松的不等于判断可以同时排除 null 和 undefined 两个值
// 但是如果用的是 x !== null ,这样就只能排除 null 一个值
}
demo15(1)
demo15(undefined)
2.4. in操作符类型缩小
type a={
swim:()=>void
}
type b={
fly:()=>void
}
type c={
swim?:()=>void, //加上 ? 表示该参数为可选参数
fly:()=>void
}
function demo16(x:a|b){
if('swim' in x){
return x.swim()
}
// 这个in操作符的作用就是判断值是否在某个东西身上,是则返回true,否则为false
// 所以上面代码表示为:'swim' 是否在 x 身上,如果在,那x必定为 type所定义的类型 a
// 故可以调用 swim()方法
}
function demo17(x:a|b|c){
if('swim' in x){
// return x.swim() 报错
// 因为加入了类型 c,且类型c身上是有 swim() 方法的,这样本身是没问题的
// 但是c身上的 swim() 方法是可选的,也就是说可能为空,所以说会报错
return (x as a).swim()
// 我们加上类型断言便可解决这个问题,即只有当 x 类型为 a 时,才会去调用 swim() 方法
}
}
2.5. instance操作符缩小
function demo18(x: Date | string){
if(x instanceof Date){
// 判断 x 是否存在 Date 这么一个方法
console.log('123')
}else{
console.log(x.toLocaleUpperCase())
}
}
demo18(new Date())
demo18('hello')
2.6. 分配缩小
let x3=Math.random() < 0.5 ? 10 : 'hello'
x3=1
console.log(x3)
x3='dd'
console.log(x3)
// x3=true //报错,因为变量x3并不具有 bool 类型
// 分配类型缩小和 let x3:string | number 类似,只是他不是
// 直接告诉变量他所拥有的类型,而是通过判断来给变量进行赋值
// 这样通过类型推断,从而获取拥有到数据类型.
// 这里需要注意的是,仅管我们是通过判断来给变量进行赋值,但是
// 我们也可以拥有所有的变量类型
2.7. 控制流分析
function demo19(){
let x:string | number | boolean
x=Math.random() < 0.5
console.log(x)
if(Math.random()<0.5){
x='hello' //把类型限制为 string
console.log(x)
}else{
x=100 //把类型限制为 number
console.log(x)
}
// 通过上面的操作,成功将返回值 x 类型限制为 string | number
return x
// 这里需要注意了,这里虽然是判断,也就是说只会有一种类型成立,
// 但是我们是可以同时拥有这两种数据类型的,和上一节分配缩小是一样的
}
let x4=demo19()
x4='hello'
x4=100
// x4=true //报错
2.8. 类型谓词
type Fish={
name:string
swim:()=>void
}
type Bird={
name:string
fly:()=>void
}
// 类型谓词是用来限制返回值的数据类型
// 类型谓词书写格式:参数 is 类型
// is是固定不变的,is左侧必须为函数本身所使用的一个参数
// is右侧必须为一个数据类型
function demo20( pet: Fish | Bird):pet is Fish{
// return true //返回值为 true 则为 Fish 数据类型
// return false //返回值为 false 则为 Bird 数据类型
return (pet as Fish).swim !== undefined
// 易错点:这里我们很容易就写成 pet.swim !== undefined 这是不对的
// 因为 pet 可能为 Bird 数据类型,而Bird数据类型没有 swim 这个方法,ts便会提示报错
// 我们需要加一个类型断言 (pet as Fish) 即代表只有当 pet 数据类型为Fish时,我们才进行接下来的操作
}
3. 类型断言
TypeScript 的类型断言(Type Assertions)是开发者向编译器表明某个值的特定类型的一种方式。类型断言允许你更具体地说明某个值的类型,而不必等待编译器的自动推断。类型断言不会在运行时产生任何影响,仅用于编译阶段的类型检查
3.1. 语法
TypeScript 提供了两种类型断言的语法:
- 尖括号语法(Angle-bracket syntax)
as
语法
// 尖括号语法类似于在值的前面加上类型
let someValue: any = "this is a string";
let strLength: number = (<string>someValue).length;
console.log(strLength); // 输出: 16
// as 语法的基本形式是在值后面使用 as Type
let someValue: any = "this is a string";
let strLength: number = (someValue as string).length;
console.log(strLength); // 输出: 16
选择合适的语法
- 在使用 JSX 语法(例如 React)时,推荐使用
as
语法,因为尖括号语法在 JSX 中会产生语法冲突。 - 除此之外,尖括号语法和
as
语法在功能上是等价的,可以根据团队的编码规范自由选择一种
3.2. 类型断言的应用场景
- DOM 操作:在操作 DOM 时,可能需要强制声明某个获取的元素类型以便调用特定的方法
let someElement = document.getElementById("myElement") as HTMLInputElement;
if (someElement) {
someElement.value = "Hello, World!";
}
- 转换类型:类型断言可以在类型兼容的转换中使用,例如从
number
转换为any
或者将any
转换为具体类型
let value: any = "this is a string";
let stringLength: number = (value as string).length;
console.log(stringLength); // 输出: 16
- 联合类型中的精准类型判断:类型断言有助于处理联合类型,从而可以更精确地调用特定类型的方法
function getLength(something: string | number): number {
if ((something as string).length !== undefined) {
return (something as string).length;
} else {
return something.toString().length;
}
}
console.log(getLength("hello")); // 输出: 5
console.log(getLength(12345)); // 输出: 5
3.3. 注意事项
- 类型安全:类型断言是开发者向编译器表明信任关系,但这也意味着开发者要确保类型断言是合理的。如果类型断言不合理,可能会在运行时引发错误。
let someValue: any = "this is a string";
let numValue: number = someValue as number; // 不安全,会导致运行时错误
- 类型兼容性:TypeScript 是一种结构性类型系统。如果类型系统中的两个类型具有兼容的结构,那么 TypeScript 允许这些类型之间进行类型断言。
interface Person {
name: string;
}
interface Employee {
name: string;
department: string;
}
let employee: Employee = {name: "Alice", department: "HR"};
let person: Person = employee as Person; // 合法,因为 `Employee` 具有 `Person` 的所有属性
- 双重断言:在某些情况下,如果需要绕过类型检查,可以使用双重断言。双重断言是指先将一个类型断言为
any
,然后再断言为目标类型。
// 应当谨慎使用双重断言,因为它可能导致不安全的类型转换
let someValue: any = "this is a string";
let valueAsNumber: number = (someValue as any) as number;
3.4. 总结
类型断言是 TypeScript 中一个强大且灵活的工具,允许开发者在需要时绕过类型检查。合理使用类型断言可以增强代码的灵活性和可操作性,但也需要注意合理性和安全性。理解并掌握类型断言的使用场景,可以让你在编写 TypeScript 代码时更加得心应手。
4. 工具类型
工具类型是 Ts 中非常重要的一个概念,对工具类型运用的程度,直接决定你TS的技术强度。在一些开源组件库或工具函数的编写中,工具类型是非常重要的。
这里主要讲解下方的几个工具类型:
Partial<T>
Required<T>
Readonly<T>
Pick<T, K>
Omit<T, K>
Record<K, T>
Exclude<T, U>
Extract<T, U>
NonNullable<T>
ReturnType<T>
InstanceType<T>
4.1. Partial
- 说明:
Partial
是一个预定义的工具类型,它将一个类型的所有属性变为可选的。 - 语法:
type Partial<T> = {
[P in keyof T]?: T[P];
};
- 示例:假设我们有一个接口
Task
,它具有多个属性:
interface Task {
title: string;
description: string;
}
现在我们想创建一个新的类型 PartialTask
,该类型将 Task
的所有属性变为可选:
type PartialTask = Partial<Task>;
let task: PartialTask = {
title: "Homework"
// description 属性可选
};
4.2. Required
- 说明:
Required
是一个预定义的工具类型,它将一个类型的所有属性变为必选的。 - 语法:
type Required<T> = {
[P in keyof T]-?: T[P];
};
- 示例:假设我们有一个接口
Task
,它具有多个可选属性:
interface Task {
title?: string;
description?: string;
}
现在我们想创建一个新的类型 RequiredTask
,该类型将 Task
的所有属性变为必选:
type RequiredTask = Required<Task>;
let task: RequiredTask = {
title: "Homework",
description: "Math"
};
4.3. Readonly
- 说明:
Readonly
是一个预定义的工具类型,它将一个类型的所有属性变为只读的。 - 语法:
type Readonly<T> = {
readonly [P in keyof T]: T[P];
};
- 示例:假设我们有一个接口
Point
,它具有多个属性:
interface Point {
x: number;
y: number;
}
现在我们想创建一个新的类型 ReadonlyPoint
,该类型将 Point
的所有属性变为只读:
type ReadonlyPoint = Readonly<Point>;
let point: ReadonlyPoint = { x: 10, y: 20 };
// point.x = 5; // Error: Cannot assign to 'x' because it is a read-only property.
4.4. Pick
- 说明:
Pick
是一个预定义的工具类型,它从类型T
中挑选出一组属性K
。 - 语法:
type Pick<T, K extends keyof T> = {
[P in K]: T[P];
};
- 示例:假设我们有一个接口
Todo
,它具有多种属性:
interface Todo {
title: string;
description: string;
completed: boolean;
}
现在我们想创建一个新的类型 TodoPreview
,该类型从 Todo
中挑选属性 title
和 completed
:
type TodoPreview = Pick<Todo, "title" | "completed">;
let todo: TodoPreview = {
title: "Clean room",
completed: false
};
4.5. Omit
- 说明:
Omit
是一个预定义的工具类型,它用于从类型中排除某些属性。换句话说,它生成一个新类型,该类型具有目标类型的部分属性,但不包括指定的那些属性 - 语法:
type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;
- 示例:
假设我们有一个接口 Person
,它具有多个属性:
interface Person {
name: string;
age: number;
address: string;
phone: string;
}
现在我们想创建一个新的类型 PersonWithoutContact
,它包含 Person
中的所有属性,但不包括 address
和 phone
。
type PersonWithoutContact = Omit<Person, "address" | "phone">;
let person: PersonWithoutContact = {
name: "Alice",
age: 30
// address 和 phone 属性被省略
};
4.6. Record
- 说明:
Record
是一个预定义的工具类型,它用于将一个类型的所有属性的值映射到另一个类型。简而言之,Record
用来创建键-值对结构,其中键的类型和值的类型是自定义的。 - 语法:
type Record<K extends keyof any, T> = {
[P in K]: T;
};
- 示例:
假设我们需要为一组用户创建一个键-值对结构,其中键是用户的 ID,值是用户的详细信息。
// 这里简单理解一下,其实 Record 属性会生成一个对象。
// 这个对象key的类型就是Record的第一个参数,这个对象value的类型就是Record的第二个参数
// 案例一
type Instance = Record<string, any>;
const aa:Instance = {xx:x} //那么 aa 就是一个对象,且key为string,value为任意类型
// 案例二
interface User {
id: number;
name: string;
email: string;
}
type Users = Record<string, User>;
const users: Users = {
"user1": { id: 1, name: "Alice", email: "alice@example.com" },
"user2": { id: 2, name: "Bob", email: "bob@example.com" }
};
在这个例子中,Users
类型被定义为一个对象,其中键为字符串类型,值为 User
的类型。这样我们就可以创建一个用户对象,其中每个用户都有一个唯一的字符串 ID。
4.7. Exclude
- 说明:
Exclude
是一个预定义的工具类型,它从类型T
中排除那些可赋值给U
的类型。 - 语法:
type Exclude<T, U> = T extends U ? never : T;
- 示例:假设我们有一个联合类型
T
,包含多个字符串字面量类型:
type T = Exclude<"a" | "b" | "c", "a">; // "b" | "c"
4.8. Extract
- 说明:
Extract
是一个预定义的工具类型,它用于从类型T
中提取那些可以赋值给U
的类型。 - 语法:
type Extract<T, U> = T extends U ? T : never;
- 示例:假设我们有一个联合类型
T
,包含多个字符串字面量类型:
type T = Extract<"a" | "b" | "c", "a" | "f">; // "a"
4.9. NonNullable
- 说明:
NonNullable
是一个预定义的工具类型,它用于从类型T
中排除null
和undefined
。 - 语法:
type NonNullable<T> = T extends null | undefined ? never : T;
- 示例:假设我们有一个联合类型
T
,包含多个类型:
type T = NonNullable<string | number | undefined>; // string | number
4.10. ReturnType
- 说明:
ReturnType
是一个预定义的工具类型,它用于获取函数类型T
的返回类型。 - 语法:
type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any;
- 示例:假设我们有一个函数
sayHello
:
function sayHello() {
return "Hello";
}
type HelloReturnType = ReturnType<typeof sayHello>; // string
4.11. InstanceType
- 说明:
InstanceType
是一个预定义的工具类型,它用于获取构造函数类型T
的实例类型。 - 语法:
type InstanceType<T extends new (...args: any) => any> = T extends new (...args: any) => infer R ? R : any;
- 示例:假设我们有一个构造函数
Person
:
class Person {
name: string;
constructor(name: string) {
this.name = name;
}
}
type PersonInstance = InstanceType<typeof Person>; // Person
非语法篇
1. 三斜杠指令
TypeScript 的三斜杠指令(Triple-Slash Directives)用于在文件之间引入额外的编译信息。它们通常写在文件的最顶端。以下是 TypeScript 支持的三种主要三斜杠指令
/// <reference path="..." />
/// <reference types="..." />
/// <reference no-default-lib="true" />
1.1. /// <reference path="..." />
- 用途
/// <reference path="..." />
指令用于声明文件间的依赖关系。它指定了一个文件的路径,并告诉编译器将该文件引入当前文件的上下文中
- 示例
假设有两个文件 a.ts
和 b.ts
:
export function greet(name: string): string {
return `Hello, ${name}`;
}
/// <reference path="a.ts" />
console.log(greet("World"));
- 解释:在这个例子中,
b.ts
使用三斜杠指令/// <reference path="a.ts" />
来引入a.ts
文件,使得b.ts
中可以访问a.ts
中定义的greet
函数
1.2. /// <reference types="..." />
- 用途
/// <reference types="..." />
指令用于引入类型声明文件。它通常用于引入位于 node_modules/@types/
目录下的类型库
- 示例
假设我们需要引入 node
的类型定义:
/// <reference types="node" />
import * as fs from 'fs';
console.log(fs.readdirSync('./'));
- 说明:在这个例子中,
/// <reference types="node" />
告诉编译器从@types/node
包中引入node
的类型声明。这样我们就可以在代码中使用和node
相关的类型定义
1.3. /// <reference no-default-lib="true" />
- 用途
/// <reference no-default-lib="true" />
指令用于禁用默认库文件的加载。它适用于希望完全控制标准库的情况下,例如为特定环境编写类型声明
- 示例
假设我们创建一个没有标准库的 TypeScript 文件:
/// <reference no-default-lib="true" />
interface CustomString {
customLength: number;
}
let example: CustomString = {customLength: 42};
- 说明:在这个例子中,
/// <reference no-default-lib="true" />
禁用了所有默认添加到 TypeScript 编译中的库文件。这意味着标准的 JavaScript 环境将不可用,只有显式声明的部分可用。
1.4. 总结
三斜杠指令在 TypeScript 中主要用于文件之间声明依赖关系和引入类型声明。以下是这些指令的总结:
/// <reference path="..." />
:声明文件间的依赖关系,指定某个文件路径。/// <reference types="..." />
:引入类型声明文件,通常用于引入node_modules/@types/
目录下的类型库。/// <reference no-default-lib="true" />
:禁用默认库文件的加载,适合完全控制标准库的情况。
这些指令增强了 TypeScript 项目中模块之间的连接和类型管理,确保代码更加模块化、可维护。希望这些详细讲解和示例能帮助你更好地理解和应用三斜杠指令。
2. 声明文件.d.ts
2.1. 安装
当使用第三方库时,需要引入它的声明文件才能获得对应的代码补全等提示功能。有些三方库内部已经有了,可以直接使用,如果没有就需要另外安装。比如express
库,源码里面是没有声明文件,所有要安装对应的声明文件
# 三方声明文件安装规则,都是以@type/开头,后面接库的名称
# 也可以在npm types上搜索对应的声明文件
npm i --save-dev @types/express
2.2. 创建
如果三方声明文件库都没有,就要手动书写声明文件,文件后缀名为.d.ts
declare
关键字可以将定义的类型暴露出来
declare var 声明全局变量
declare function 声明全局方法
declare class 声明全局类
declare enum 声明全局枚举类型
declare namespace 声明(含有子属性的)全局对象
interface 和 type 声明全局类型
3. 配置文件详解
安装安装安装{
"compilerOptions": {
/* 请访问 https://aka.ms/tsconfig,了解有关此文件的详细信息 */
/* 项目 */
// "incremental": true, /* 保存 .tsbuildinfo 文件以允许项目增量编译。 */
// "composite": true, /* 启用允许将 TypeScript 项目与项目引用一起使用的约束。 */
// "tsBuildInfoFile": "./.tsbuildinfo", /* 指定 .tsbuildinfo 增量编译文件的路径。 */
// "disableSourceOfProjectReferenceRedirect": true, /* 在引用复合项目时禁用首选源文件而不是声明文件。 */
// "disableSolutionSearching": true, /* 在编辑时选择项目退出多项目引用检查。 */
// "disableReferencedProjectLoad": true, /* 减少 TypeScript 自动加载的项目数。 */
/* 语言和环境 */
"target": "es2016", /* 为发出的 JavaScript 设置 JavaScript 语言版本并包含兼容的库声明。 */
// "lib": [], /* 指定一组描述目标运行时环境的捆绑库声明文件。 */
// "jsx": "preserve", /* 指定生成的 JSX 代码。 */
// "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */
// "emitDecoratorMetadata": true, /* 为源文件中的修饰声明发出设计类型元数据。 */
// "jsxFactory": "", /* 指定在将 React JSX 发出设定为目标时要使用的 JSX 中心函数,例如 “react.createElement” 或 “h”。 */
// "jsxFragmentFactory": "", /* 指定在将 React JSX 发出设定为目标时用于片段的 JSX 片段引用,例如 “React.Fragment” 或 “Fragment”。 */
// "jsxImportSource": "", /* 指定使用 “jsx: react-jsx*” 时用于导入 JSX 中心函数的模块说明符。 */
// "reactNamespace": "", /* 指定为 “createElement” 调用的对象。这仅适用于将 “react” JSX 发出设定为目标的情况。 */
// "noLib": true, /* 禁用包括任何库文件(包括默认的 lib.d.ts)。 */
// "useDefineForClassFields": true, /* 发出符合 ECMAScript 标准的类字段。 */
// "moduleDetection": "auto", /* 控制用于检测模块格式 JS 文件的方法。 */
/* 模块 */
"module": "commonjs", /* 指定生成的模块代码。 */
// "rootDir": "./", /* 指定源文件中的根文件夹。 */
// "moduleResolution": "node10", /* 指定 TypeScript 如何从给定的模块说明符查找文件。 */
// "baseUrl": "./", /* 指定基目录以解析非相关模块名称。 */
// "paths": {}, /* 指定一组将导入重新映射到其他查找位置的条目。 */
// "rootDirs": [], /* 允许在解析模块时将多个文件夹视为一个文件夹。 */
// "typeRoots": [], /* 指定多个行为类似于 “./node_modules/@types” 的文件夹。 */
// "types": [], /* 指定要包含的类型包名称,而无需在源文件中引用。 */
// "allowUmdGlobalAccess": true, /* 允许从模块访问 UMD 变量全局。 */
// "moduleSuffixes": [], /* 解析模块时要搜索的文件名后缀列表。 */
// "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */
// "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
// "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
// "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
// "resolveJsonModule": true, /* 启用导入 .json 文件。 */
// "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
// "noResolve": true, /* 禁止 “import”、“require” 或 “<reference>” 扩展 TypeScript 应添加到项目的文件数。 */
/* JavaScript 支持 */
// "allowJs": true, /* 允许 JavaScript 文件成为程序的一部分。使用 “checkJS” 选项从这些文件中获取错误。 */
// "checkJs": true, /* 在已检查类型的 JavaScript 文件中启用错误报告。 */
// "maxNodeModuleJsDepth": 1, /* 指定用于从 “node_modules” 检查 JavaScript 文件的最大文件夹深度。仅适用于 “allowJs”。 */
/* 发出 */
// "declaration": true, /* 从项目的 TypeScript 和 JavaScript 文件生成 .d.ts 文件。 */
// "declarationMap": true, /* 为 d.ts 文件创建源映射。 */
// "emitDeclarationOnly": true, /* 仅输出 d.ts 文件,而不输出 JavaScript 文件。 */
// "sourceMap": true, /* 为发出的 JavaScript 文件创建源映射文件。 */
// "inlineSourceMap": true, /* 在发出的 JavaScript 中包括源映射文件。 */
// "outFile": "./", /* 指定将所有输出捆绑到一个 JavaScript 文件中的文件。如果 “declaration” 为 true,还要指定一个捆绑所有 .d.ts 输出的文件。 */
// "outDir": "./", /* 为所有已发出的文件指定输出文件夹。 */
// "removeComments": true, /* 禁用发出注释。 */
// "noEmit": true, /* 禁用从编译发出文件。 */
// "importHelpers": true, /* 允许每个项目从 tslib 导入帮助程序函数一次,而不是将它们包含在每个文件中。 */
// "importsNotUsedAsValues": "remove", /* 指定仅用于类型的导入的发出/检查行为。 */
// "downlevelIteration": true, /* 发出更合规但更详细且性能较低的 JavaScript 进行迭代。 */
// "sourceRoot": "", /* 指定调试程序的根路径以查找引用源代码。 */
// "mapRoot": "", /* 指定调试程序应将映射文件放置到的位置而不是生成的位置。 */
// "inlineSources": true, /* 在发出的 JavaScript 内的源映射中包含源代码。 */
// "emitBOM": true, /* 在输出文件的开头发出一个 UTF-8 字节顺序标记(BOM)。 */
// "newLine": "crlf", /* 设置发出文件的换行符。 */
// "stripInternal": true, /* 禁用在其 JSDoc 注释中包含 “@internal” 的发出声明。 */
// "noEmitHelpers": true, /* 在已编译输出中禁用生成自定义帮助程序函数(如 “__extends”)。 */
// "noEmitOnError": true, /* 禁用在报告了任何类型检查错误时发出文件。 */
// "preserveConstEnums": true, /* 在生成的代码中禁用擦除 “const enum” 声明。 */
// "declarationDir": "./", /* 指定已生成声明文件的输出目录。 */
// "preserveValueImports": true, /* 保留 JavaScript 输出中未使用的导入值,否则将删除这些值。 */
/* 互操作约束 */
// "isolatedModules": true, /* 确保可以安全地转译每个文件,而无需依赖其他导入。 */
// "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */
// "allowSyntheticDefaultImports": true, /* 当模块没有默认导出时,允许“从 y 导入 x”。 */
"esModuleInterop": true, /* 发出其他 JavaScript 以轻松支持导入 CommonJS 模块。这将启用 “allowSyntheticDefaultImports” 以实现类型兼容性。 */
// "preserveSymlinks": true, /* 禁用将符号链接解析为其实际路径。这会关联到节点中的同一标志。 */
"forceConsistentCasingInFileNames": true, /* 确保导入中的大小写正确。 */
/* 类型检查 */
"strict": true, /* 启用所有严格类型检查选项。 */
// "noImplicitAny": true, /* 对具有隐式 “any” 类型的表达式和声明启用错误报告。 */
// "strictNullChecks": true, /* 进行类型检查时,请考虑 “null” 和 “undefined”。 */
// "strictFunctionTypes": true, /* 分配函数时,请检查以确保参数和返回值与子类型兼容。 */
// "strictBindCallApply": true, /* 检查 “bind”、“call” 和 “apply” 方法的参数是否与原始函数匹配。 */
// "strictPropertyInitialization": true, /* 检查是否有已声明但未在构造函数中设置的类属性。 */
// "noImplicitThis": true, /* 在 “this” 的类型为 “any” 时启用错误报告。 */
// "useUnknownInCatchVariables": true, /* 将 catch 子句变量默认为 “unknown” 而不是 “any”。 */
// "alwaysStrict": true, /* 请确保始终发出 “se strict”。 */
// "noUnusedLocals": true, /* 在未读取局部变量时启用错误报告。 */
// "noUnusedParameters": true, /* 在未读取函数参数时引发错误。 */
// "exactOptionalPropertyTypes": true, /* 将可选属性类型解释为已写,而不是添加 "undefined"。 */
// "noImplicitReturns": true, /* 为未在函数中显式返回的代码路径启用错误报告。 */
// "noFallthroughCasesInSwitch": true, /* 为 switch 语句中的故障案例启用错误报告。 */
// "noUncheckedIndexedAccess": true, /* 使用索引访问时,将 “undefined” 添加到类型。 */
// "noImplicitOverride": true, /* 确保使用替代修饰符标记派生类中的替代成员。 */
// "noPropertyAccessFromIndexSignature": true, /* 对使用索引类型声明的键强制使用索引访问器。 */
// "allowUnusedLabels": true, /* 对未使用的标签禁用错误报告。 */
// "allowUnreachableCode": true, /* 对无法访问的代码禁用错误报告。 */
/* 完成度 */
// "skipDefaultLibCheck": true, /* 跳过 TypeScript 附带的类型检查 .d.ts 文件。 */
"skipLibCheck": true /* 跳过对所有 .d.ts 文件的类型检查。 */
},
"include": ["src/**/*.ts", "demo.ts"] , /* 指定包含的目录、文件*/
"exclude": ["test.ts"], /* 排除的目录、文件*/
}
插入:小编自己封装了一个大文件上传的工具函数,支持切片上传、错误重试、上传进度、暂停和继续等,目前已发布在npm官网,感兴趣的可以看看。
https://www.npmjs.com/package/enlarge-file-upload?activeTab=versions
下载命令:npm i enlarge-file-upload