前端TS高阶篇

本次一共推出三篇文章,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 提供了两种类型断言的语法:

  1. 尖括号语法(Angle-bracket syntax)
  2. 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. 类型断言的应用场景
  1. DOM 操作:在操作 DOM 时,可能需要强制声明某个获取的元素类型以便调用特定的方法
let someElement = document.getElementById("myElement") as HTMLInputElement;
if (someElement) {
    someElement.value = "Hello, World!";
}
  1. 转换类型:类型断言可以在类型兼容的转换中使用,例如从 number 转换为 any 或者将 any 转换为具体类型
let value: any = "this is a string";
let stringLength: number = (value as string).length;

console.log(stringLength);  // 输出: 16
  1. 联合类型中的精准类型判断:类型断言有助于处理联合类型,从而可以更精确地调用特定类型的方法
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. 注意事项
  1. 类型安全:类型断言是开发者向编译器表明信任关系,但这也意味着开发者要确保类型断言是合理的。如果类型断言不合理,可能会在运行时引发错误。
let someValue: any = "this is a string";
let numValue: number = someValue as number; // 不安全,会导致运行时错误
  1. 类型兼容性: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` 的所有属性
  1. 双重断言:在某些情况下,如果需要绕过类型检查,可以使用双重断言。双重断言是指先将一个类型断言为 any,然后再断言为目标类型。
// 应当谨慎使用双重断言,因为它可能导致不安全的类型转换
let someValue: any = "this is a string";
let valueAsNumber: number = (someValue as any) as number;
3.4. 总结

类型断言是 TypeScript 中一个强大且灵活的工具,允许开发者在需要时绕过类型检查。合理使用类型断言可以增强代码的灵活性和可操作性,但也需要注意合理性和安全性。理解并掌握类型断言的使用场景,可以让你在编写 TypeScript 代码时更加得心应手。

4. 工具类型

工具类型是 Ts 中非常重要的一个概念,对工具类型运用的程度,直接决定你TS的技术强度。在一些开源组件库或工具函数的编写中,工具类型是非常重要的。

这里主要讲解下方的几个工具类型:

  1. Partial<T>
  2. Required<T>
  3. Readonly<T>
  4. Pick<T, K>
  5. Omit<T, K>
  6. Record<K, T>
  7. Exclude<T, U>
  8. Extract<T, U>
  9. NonNullable<T>
  10. ReturnType<T>
  11. InstanceType<T>
4.1. Partial
  1. 说明:Partial 是一个预定义的工具类型,它将一个类型的所有属性变为可选的。
  2. 语法:
type Partial<T> = {
  [P in keyof T]?: T[P];
};
  1. 示例:假设我们有一个接口 Task,它具有多个属性:
interface Task {
  title: string;
  description: string;
}

现在我们想创建一个新的类型 PartialTask,该类型将 Task 的所有属性变为可选:

type PartialTask = Partial<Task>;

let task: PartialTask = {
  title: "Homework"
  // description 属性可选
};
4.2. Required
  1. 说明:Required 是一个预定义的工具类型,它将一个类型的所有属性变为必选的。
  2. 语法:
type Required<T> = {
  [P in keyof T]-?: T[P];
};
  1. 示例:假设我们有一个接口 Task,它具有多个可选属性:
interface Task {
  title?: string;
  description?: string;
}

现在我们想创建一个新的类型 RequiredTask,该类型将 Task 的所有属性变为必选:

type RequiredTask = Required<Task>;

let task: RequiredTask = {
  title: "Homework",
  description: "Math"
};
4.3. Readonly
  1. 说明:Readonly 是一个预定义的工具类型,它将一个类型的所有属性变为只读的。
  2. 语法:
type Readonly<T> = {
  readonly [P in keyof T]: T[P];
};
  1. 示例:假设我们有一个接口 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
  1. 说明:Pick 是一个预定义的工具类型,它从类型 T 中挑选出一组属性 K
  2. 语法:
type Pick<T, K extends keyof T> = {
  [P in K]: T[P];
};
  1. 示例:假设我们有一个接口 Todo,它具有多种属性:
interface Todo {
  title: string;
  description: string;
  completed: boolean;
}

现在我们想创建一个新的类型 TodoPreview,该类型从 Todo 中挑选属性 titlecompleted

type TodoPreview = Pick<Todo, "title" | "completed">;

let todo: TodoPreview = {
  title: "Clean room",
  completed: false
};
4.5. Omit
  1. 说明:Omit 是一个预定义的工具类型,它用于从类型中排除某些属性。换句话说,它生成一个新类型,该类型具有目标类型的部分属性,但不包括指定的那些属性
  2. 语法:
type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;
  1. 示例:

假设我们有一个接口 Person,它具有多个属性:

interface Person {
  name: string;
  age: number;
  address: string;
  phone: string;
}

现在我们想创建一个新的类型 PersonWithoutContact,它包含 Person 中的所有属性,但不包括 addressphone

type PersonWithoutContact = Omit<Person, "address" | "phone">;

let person: PersonWithoutContact = {
  name: "Alice",
  age: 30
  // address 和 phone 属性被省略
};
4.6. Record
  1. 说明:Record 是一个预定义的工具类型,它用于将一个类型的所有属性的值映射到另一个类型。简而言之,Record 用来创建键-值对结构,其中键的类型和值的类型是自定义的。
  2. 语法:
type Record<K extends keyof any, T> = {
  [P in K]: T;
};
  1. 示例:

假设我们需要为一组用户创建一个键-值对结构,其中键是用户的 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
  1. 说明:Exclude 是一个预定义的工具类型,它从类型 T 中排除那些可赋值给 U 的类型。
  2. 语法:
type Exclude<T, U> = T extends U ? never : T;
  1. 示例:假设我们有一个联合类型 T,包含多个字符串字面量类型:
type T = Exclude<"a" | "b" | "c", "a">; // "b" | "c"
4.8. Extract
  1. 说明:Extract 是一个预定义的工具类型,它用于从类型 T 中提取那些可以赋值给 U 的类型。
  2. 语法:
type Extract<T, U> = T extends U ? T : never;
  1. 示例:假设我们有一个联合类型 T,包含多个字符串字面量类型:
type T = Extract<"a" | "b" | "c", "a" | "f">; // "a"
4.9. NonNullable
  1. 说明:NonNullable 是一个预定义的工具类型,它用于从类型 T 中排除 nullundefined
  2. 语法:
type NonNullable<T> = T extends null | undefined ? never : T;
  1. 示例:假设我们有一个联合类型 T,包含多个类型:
type T = NonNullable<string | number | undefined>; // string | number
4.10. ReturnType
  1. 说明:ReturnType 是一个预定义的工具类型,它用于获取函数类型 T 的返回类型。
  2. 语法:
type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any;
  1. 示例:假设我们有一个函数 sayHello
function sayHello() {
  return "Hello";
}

type HelloReturnType = ReturnType<typeof sayHello>; // string
4.11. InstanceType
  1. 说明:InstanceType 是一个预定义的工具类型,它用于获取构造函数类型 T 的实例类型。
  2. 语法:
type InstanceType<T extends new (...args: any) => any> = T extends new (...args: any) => infer R ? R : any;
  1. 示例:假设我们有一个构造函数 Person
class Person {
  name: string;
  constructor(name: string) {
    this.name = name;
  }
}

type PersonInstance = InstanceType<typeof Person>; // Person

非语法篇

1. 三斜杠指令

TypeScript 的三斜杠指令(Triple-Slash Directives)用于在文件之间引入额外的编译信息。它们通常写在文件的最顶端。以下是 TypeScript 支持的三种主要三斜杠指令

  1. /// <reference path="..." />
  2. /// <reference types="..." />
  3. /// <reference no-default-lib="true" />
1.1. /// <reference path="..." />
  1. 用途

/// <reference path="..." /> 指令用于声明文件间的依赖关系。它指定了一个文件的路径,并告诉编译器将该文件引入当前文件的上下文中

  1. 示例

假设有两个文件 a.tsb.ts

export function greet(name: string): string {
    return `Hello, ${name}`;
}
/// <reference path="a.ts" />

console.log(greet("World"));


 

  1. 解释:在这个例子中,b.ts 使用三斜杠指令 /// <reference path="a.ts" /> 来引入 a.ts 文件,使得 b.ts 中可以访问 a.ts 中定义的 greet 函数
1.2. /// <reference types="..." />
  1. 用途

/// <reference types="..." /> 指令用于引入类型声明文件。它通常用于引入位于 node_modules/@types/ 目录下的类型库

  1. 示例

假设我们需要引入 node 的类型定义:

/// <reference types="node" />

import * as fs from 'fs';

console.log(fs.readdirSync('./'));
  1. 说明:在这个例子中,/// <reference types="node" /> 告诉编译器从 @types/node 包中引入 node 的类型声明。这样我们就可以在代码中使用和 node 相关的类型定义
1.3. /// <reference no-default-lib="true" />
  1. 用途

/// <reference no-default-lib="true" /> 指令用于禁用默认库文件的加载。它适用于希望完全控制标准库的情况下,例如为特定环境编写类型声明

  1. 示例

假设我们创建一个没有标准库的 TypeScript 文件:

/// <reference no-default-lib="true" />

interface CustomString {
    customLength: number;
}

let example: CustomString = {customLength: 42};
  1. 说明:在这个例子中,/// <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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值