TypeScript手把手教程,简单易懂

简介

TypeScript (简称 ts)是 JavaScript 的一个超集,主要提供了类型系统对 ES6 的支持,它由 Microsoft 开发
超集:也就是说 typescript有javascript没有的功能用来增强javascript

准备工作

  1. 安装(在node环境下)

    npm i  -g  typescript
    or
    yarn  global add  typescript
    
  2. 检查是否安装成功
    tsc -v 注意:tsc只有安装完typescript才有
    ok

  3. 体验
    创建文件夹demo,在此文件下创建helloTs.ts,然后文件中,随便写点什么

    const s:string = "床前明月光,疑是地上霜";
    console.log(s);
    

    控制台执行 tsc helloTs.ts 命令,目录下生成了一个同名的 helloTs.js 文件,代码如下

    var s = "床前明月光,疑是地上霜";
    console.log(s);
    

    通过tsc命令,发现我们的typescript代码被转换成了熟悉的js代码
    我们接着执行

    node helloTs.js
    

    即可看到输出结果

    以上代码不理解没事,好好阅读练习下面详解就是发现新大陆

工作流

1
由于ts代码无法在浏览器中运行,所以编写的ts代码(Code.ts)由ts的编译器tsc进行编译代码(Code.ts)编译成功后会自动创建改ts所对应的js代码(Code.js)

JavaScript 和 TypeScript 的区别

  1. JavaScript:边解释边执行,错误只有在运行的时候才能发现
  2. TypeScript:先编译再执行,在写的时候就会发现错误了(ts不能直接执行,需要先编译成 js )

ts的好处
有利于规范我们的代码、代码编译阶段能更好的发现错误、强类型语言

入门必须

类型注解

就是给变量添加类型约束,可以显示标记出代码中的意外行为,从而降低了发生错误的可能性

格式:let 变量名: 类型 = 初始值
例:let name:string = ‘张三’

已知js原有类型:

  • 原始类型:string、number、boolean、null、undefined、symbol
  • 对象类型:object(包括,数组、对象、函数等对象)

ts新增类型:tuple(元组)、enum(枚举)、void、never、any、unknown、联合类型、字面量类型

用法
  1. 原有类型

    // 字符串类型
    let myName: string = '张三'
    
    // 数值类型
    let age: number = 18
    
    // 布尔类型
    let isLoading: boolean = false
    
    // undefined
    let un: undefined = undefined
    
    // null
    let timer: null = null
    
    // symbol
    let uniKey: symbol = Symbol()
    
    //数组
    let array1: number[] = [1,2,3,4,5]
    //or
    let array2: Array<number> = [1,2,3,4,5]
    
    //对象
    let obj: {name:string, age:number} = {name: '张三', age: 18}
    
    //函数
    let fun: (num1: number, num2: number) => number = function (num1: number, num2: number) {
    	return num1 + num2;
    }
    console.log(fun(1, 2)); // 3
    
    
    // 注意冒号后面是什么类型,值就必须是什么类型,否则编译会报相关错误 ↓
    // Type 'string' is not assignable to type 'number'.
    

    注意
    默认情况下(非严格模式) null 和 undefined 是所有类型的子类型。 就是说你可以把 null 和 undefined 赋值给其他类型
    如果你在tsconfig.json指定了"strictNullChecks":true ,null 和 undefined 只能赋值给 void 和它们各自的类型。

  2. 新增类型

  • tuple(元组)
    它约定了的元素个数
    它约定了特定索引对应的数据类型

    let person: [number,string] = [1, '张三']
    
  • enum(枚举)
    使用枚举我们可以定义一些有名字的数字常量。枚举通过enum关键字定义。

    //定义一个颜色枚举类
    enum Color{
    	red,
    	green,
    	blue,
    }
    //使用
    let color = Color.red;
    console.log(color) // 0
    //注意: 枚举中的对应的值默认从0开始以此类推
    //修改其值
    enum Color2{
    	red = 'red',
    	green = 10,
    	blue = 'blue'
    }
    
  • void
    通常用于函数返回值,定义一个函数没有返回任何东西,可以认为返回void
    可以用到void 有以下几种情况:

    • 函数没写return
    • 只写了 return, 没有具体的返回值
    • return 的是 undefined
    // 如果什么都不写,此时,add 函数的返回值类型为: void
    const add = () => {}
    
    // 如果return之后什么都不写,此时,add 函数的返回值类型为: void
    const add2 = () => { return }
    
    const add3 = (): void => {
      // 此处,返回的 undefined 是 JS 中的一个值
      return undefined
    }
    // 这种写法是明确指定函数返回值类型为 void,与上面不指定返回值类型相同
    const add4 = (): void => {}
    
  • never
    通常应用于函数返回值,当函数未执行完时改函数的返回值为never

    // 表示永远不会有返回结果
    function throwError(message:string, errorCode:number): never { 
    	throw {
    		message,
    		errorCode
    	}
    } 
    
  • any
    表示任意类型,对声明该any类型的变量它的值可以是任意类型

    let n: any; //表示该变量 n 的值可以是任意类型
    n = 123;
    n = '123';
    n = true;
    // ...
    
  • unknown
    表示未知类型的值,也可是任意类型

    let n: unknown; //表示该变量 n 的值可以是任意类型
    n = 123;
    n = '123';
    n = true;
    // ...
    

    拓展》》》
    any、unknown 区别?
    any 类型的变量可以直接赋值给其他变量
    unknown 类型的变量不能直接赋值给其他变量

    let a:any
    a= 123;
    a= 'object'
    let b: string
    b = a  // ok
    
    let c: unknown;
    c = 123
    c = '123'
    let d: number;
    d = c  // Type 'unknown' is not assignable to type 'number'.
    

类型断言

就是告诉编译器,我知道这个值是什么类型,也知道自己在干什么
格式: 1. <类型>变量名
            2. 变量名 as 类型
例如:

// 返回一个数字或字符串的长度
function getString(val: string | number): number {
  // 此时ts类型推导不知道val是string还是number,需要指定这个val此时的类型是string
  if ((<string>val).length) {
    // 使用第二种断言格式
    return (val as string).length;
  } else {
    // 此时说明val的类型的number
    return val.toString().length;
  }
}
console.log(getString(123)); // 3
console.log(getString("1234")); // 4

类型别名

在我们定义类型的时候,有时候自己定义的类型名往往很长,这个时候就需要在定义个别名,方便书写。
格式:type 别名 = 类型

type s = string // 定义

const str1:s = 'abc' // 使用
const str2:string = 'abc'

作用:

  • 给类型起别名
  • 定义了新类型

使用场景:给复杂的类型起个别名,比如:多个联合类型

 type NewType = string | number

 let a: NewType = 1
 let b: NewType = '1'

联合类型

需求:如何定义一个变量可以是 string 也可以是 number 类型? 这个时候,前面所学的已经不能满足我们的需求了,就需要用到一个新的类型 - 联合类型。

let a: number | string; // 变量a可以写两个类型
a = 123;
a = '123';
a = true; // 报错 Type 'boolean' is not assignable to type 'string | number'.

注意:冒号后面的类型可以有多个 用 | 竖线分割;例如:let b: number | string | null | …;
由两个或多个其他类型组成的类型,表示可以是这些类型中的任意一种。不要和 js 中的 || 搞混哦

字面量类型

在 TypeScript 中,字面量不仅可以表示值,还可以表示类型,即所谓的字面量类型。TypeScript 支持 3 种字面量类型:字符串字面量类型、数字字面量类型、布尔字面量类型。对应的字符串字面量、数字字面量、布尔字面量分别拥有与其值一样的字面量类型。
说白了就是某个变量的类型是一个或多个固定的值就是字面量类型

let str: 'hello world' = 'hello world'; // 表示该 str 值必须是 hello world
let num: 996 = 996; // 表示该 num 值必须是 996
let bool: true = true; // 表示该 bool 值必须是 true

//搭配联合类型使用
let age: 18 | 20 | 25 | 30; // age的值必须是 冒号后面类型其中一个
age = 18; //ok
age = 60;// 报错 Type '60' is not assignable to type '18 | 20 | 25 | 30'.

// 数字字面量类型也是一样的:
function compare(a: string, b: string): -1 | 0 | 1 {
  return a === b ? 0 : a > b ? 1 : -1;
}
字面量推断

当你初始化变量为一个对象的时候,TypeScript 会假设这个对象的属性的值未来会被修改,举个例子,如果你写下这样的代码:

const obj = { counter: 0 };
if (someCondition) {
  obj.counter = 1;
}

TypeScript 并不会认为 obj.counter 之前是 0, 现在被赋值为 1 是一个错误。换句话说,obj.counter 必须是 number 类型,但不要求一定是 0,因为类型可以决定读写行为。

这也同样应用于字符串:

//以declare声明的变量和模块后,其他地方不需要引入,就可以直接使用了;
//declare就是告诉TS编译器你担保这些变量和模块存在,并声明了相应类型,编译的时候不需要提示错误!
declare function handleRequest(url: string, method: "GET" | "POST"): void;

const req = { url: "https://example.com", method: "GET" };
handleRequest(req.url, req.method);

// Argument of type 'string' is not assignable to parameter of type '"GET" | "POST"'.

在上面这个例子里,req.method 被推断为 string ,而不是 “GET”,因为在创建 req 和 调用 handleRequest 函数之间,可能还有其他的代码,或许会将 req.method 赋值一个新字符串比如 “Guess” 。所以 TypeScript 就报错了。

有两种方式可以解决:

  1. 添加一个类型断言改变推断结果:
    // Change 1:
    const req = { url: "https://example.com", method: "GET" as "GET" };
    // Change 2
    handleRequest(req.url, req.method as "GET");
    
    修改 1 表示“我有意让 req.method 的类型为字面量类型 “GET”,这会阻止未来可能赋值为 “Guess” 等字段”。
    修改 2 表示“我知道 req.method 的值是 “GET””。
  2. 你也可以使用 as const 把整个对象转为一个类型字面量:
    const req = { url: "https://example.com", method: "GET" } as const;
    handleRequest(req.url, req.method);
    
    as const 效果跟 const 类似,但是对类型系统而言,它可以确保所有的属性都被赋予一个字面量类型,而不是一个更通用的类型比如 string 或者 number 。

函数

和JavaScript一样,TypeScript函数可以创建有名字的函数、箭头函数和匿名函数还是自执行函数。 你可以随意选择适合应用程序的方式,不论是定义一系列API函数还是只使用一次的函数

// 普通函数
function 函数名(形参1: 类型=默认值, 形参2:类型=默认值,...): 返回值类型 { }
// 声明式实际写法:
function add(num1: number, num2: number): number {
  return num1 + num2
}

// 箭头函数
const 函数名(形参1: 类型=默认值, 形参2:类型=默认值, ...):返回值类型 => { }
const add2 = (a: number =100, b: number = 100): number =>{
   return a + b
 }
 // 注意: 箭头函数的返回值类型要写在参数小括号的后面
函数-可选参数

使用函数实现某个功能时,参数可以传也可以不传。

例如:数组的 slice 方法,可以 slice() 也可以 slice(1) 还可以 slice(1, 3) 那么就可以定义可选参数 语法:

function slice (a?: number, b?: number) {
    // ? 跟在参数名字的后面,表示可选的参数
    // 注意:可选参数只能在 必须参数的后面
    // 如果可选参数在必选参数的前面,会报错
    console.log(111);
}
slice()
slice(1)
slice(1,2)

与js的类相似,可以理解为对象的模板,包含属性和方法
格式: class 类名 (类名首字母大写)

class Greeter {
    // 属性
	greeting: string;
	// 构造函数
    constructor(message: string) {
        this.greeting = message;
}
	// 方法
    greet() {
        return "Hello, " + this.greeting;
    }
}
//根据类的构造函数创建对象
let greeter = new Greeter("world");

类的修饰符
  1. 访问修饰符
    public声明属性和方法(默认) 在哪个地方都可以访问属性、方法

    class Point {
      public x: number;
      public y: number;
      constructor(x: number, y: number) {
        this.x = x;
        this.y = y;
      }
      public getPosition() {
        return `(${this.x}, ${this.y})`;
      }
    }
    
    const point = new Point(1, 2)
    console.log(point.x)   // 1
    console.log(point.y)   // 2
    console.log(point.getPosition())  // (1, 2)
    

    private声明属性和方法 将属性和方法私有化 外界不能访问

    class Parent {
      private age: number;
      constructor(age: number) {
        this.age = age;
      }
    }
    const p = new Parent(18);
    
    console.log(p);  // { age: 18 }
    console.log(p.age); // 报错 Property 'age' is private and only accessible within class 'Parent'.
    console.log(Parent.age); // 报错 Property 'age' does not exist on type 'typeof Parent'.
    
    class Child extends Parent {
      constructor(age: number) {
        super(age);
        console.log(super.age); // Property 'age' is private and only accessible within class 'Parent'
      }
    }
    

    protected声明属性和方法 与private相似,区别是在继承中子可以访问父的protected

    class Parent {
      protected age: number;
      constructor(age: number) {
        this.age = age;
      }
      protected getAge() {
        return this.age;
      }
    }
    
    const p = new Parent(18);
    console.log(p.age); // 报错 Property 'age' is protected and only accessible within class 'Parent' and its subclasses.
    console.log(Parent.age); // 报错 Property 'age' does not exist on type 'typeof Parent'.
    class Child extends Parent {
      constructor(age: number) {
        super(age);
        console.log(super.getAge());
      }
    }
    
    new Child(19)
    
  2. 只读修饰符
    在类中可以使用readonly关键字将属性设置为只读

    class UserInfo {
      readonly name: string;
      constructor(name: string) {
        this.name = name;
      }
    }
    const user = new UserInfo("TypeScript");
    user.name = "haha"; // error Cannot assign to 'name' because it is a read-only property
    
  3. 静态修饰符
    在类中可以使用static关键字将属性或方法设置为静态类型

    class Parent {
      static age: number = 18;
      static getAge() {
        return Parent.age;
      }
      constructor() {
        //
      }
    }
    // 静态类型不用实例化对象直接用 类名. 的方式调用
    console.log(Parent.age); // 18
    console.log(Parent.getAge()) // 18
    
类的继承

与js的继承相似,通常用继承来扩展现有的类。继承之后,子类会拥有父类的一切属性和方法
格式:class 子类 extends 父类

// 创建父类
class Parent {
    name: string;
    constructor(name: string) {
        this.name = name
    }
    getName() {
        return this.name;
    }
}
// 创建子类并继承父
class Child extends Parent {
	//构造函数
    constructor(childName: string) {
        super(childName) // 将子类创建时传入的值 给到父构造函数
    }
    testFn() {
        console.log(this.name)
        console.log(this.getName()); 
    }
}

const c = new Child('张三');
c.testFn();

注意点:

  • 在构造函数中super()作为方法表示父类的构造函数,super作为对象时,在普通方法中,指向父类的原型对象;
  • 如果在子类中写了构造函数,就必须调用父类的构造函数
存取器getters/setters

TypeScript支持通过getters/setters来截取对对象成员的访问。 它能帮助你有效的控制对对象成员的访问。

class Demo {
	// 私有属性外界不能访问,可以通过存取器进行控制
    private _name: string;
    private _age: number;
    constructor(name: string, age: number) {
        this._name = name;
        this._age = age;
    }
    get name() { // 获取时执行
        return this._name;
    }
    set name(val: string) { // 修改时执行
        this._name = val
    }
}
const d = new Demo('a',10);
d.name = 'abc'
console.log(d.name)

注意:只带有 get不带有 set的存取器自动被推断为 readonly

接口

当一个对象类型被多次使用时,有如下两种方式来来描述对象的类型,以达到复用的目的:

  • 类型别名,type
  • 接口,interface

说白了也就是对对象和类进行约束限制的一种方式

格式:
interface 接口名 {属性1: 类型1, 属性2: 类型2}

// 这里用 interface 关键字来声明接口
interface IGoodItem  {
	// 接口名称(比如,此处的 IPerson),可以是任意合法的变量名称,推荐以 `I` 开头
   name: string, 
   price: number, 
   func: ()=>string
}

// 声明接口后,直接使用接口名称作为变量的类型
const good1: IGoodItem = {
   name: '手表',
   price: 200,
   func: function() {
       return '看时间'
   }
}
const good2: IGoodItem = {
    name: '手机',
    price: 2000,
    func: function() {
        return '打电话'
    }
}

接口和类型 的区别 interface(接口)和 type(类型别名)的对比:

  • 相同点:都可以给对象指定类型
  • 不同点:
    • 接口,只能为对象指定类型。它可以继承,可以同时定义多个同名接口(同名接口会自动合并)。
    • 类型别名,不仅可以为对象指定类型,实际上可以为任意类型指定别名,唯一
// 接口的写法-------------
interface IPerson {
	name: string,
	age: number
}

const user1:IPerson = {
	name: 'a',
	age: 20
}

// type的写法-------------
type Person  = {
	name: string,
	age: number
}
const user2:Person = {
	name: 'b',
	age: 20
}
接口继承

如果两个接口之间有相同的属性或方法,可以将公共的属性或方法抽离出来,通过继承来实现复用
格式:
interface 接口2 extends 接口1 {
   属性1: 类型1, // 接口2中特有的类型
}

interface a { x: number; y: number }
// 继承 a
// 使用 extends(继承)关键字实现了接口
interface b extends a {
 z: number
}
// 继承后,b 就有了 a 的所有属性和方法(此时,b 同时有 x、y、z 三个属性)

泛型

就是当类型尚不明确时,可以用类型变量暂时替代,当使用时在明确指定或不指定,TypeScript会根据值进行类型推断,通常用于类、接口和函数 (也就是为了更好的重用)

泛型语法

对于刚接触 TypeScript 泛型的小伙伴来说,首次看到 语法会感到陌生。其实它没有什么特别,就像传递参数一样,我们传递了我们想要用于特定函数调用的类型。
222
参考上面的图片,当我们调用 identity<number>(1) ,number 类型就像参数 1 一样,它将在出现 T 的任何位置填充该类型。图中 内部的 T 被称为类型变量,它是我们希望传递给 identity 函数的类型占位符,同时它被分配给 value 参数用来代替它的类型:此时 T 充当的是类型,而不是特定的 number 类型。

其中 T 代表 Type,在定义泛型时通常用作第一个类型变量名称。但实际上 T 可以用任何有效名称代替。除了 T 之外,以下是常见泛型变量代表的意思:

  • K(Key):表示对象中的键类型;
  • V(Value):表示对象中的值类型;
  • E(Element):表示元素类型。

注意:泛型类型可以有多个或一个以逗号(,)进行分割,比如<T,…>

function identity <T, U>(value: T, message: U) : T {
  console.log(message);
  return value;
}

console.log(identity<Number, string>(68, "Semlinker"));

4444

泛型类

泛型应用于类上面

class Person<T>{
    private _value: T;
    constructor(val: T) {
        this._value = val;
    }
}
let p = new Person<number>(12)

如上,表示传递一个T类型,在new的时候才把具体类型传入。其中T(Type)是变量可更改,但通常比较常见就是写T,T可以理解成占位符,当进行实例化时传入类型填充此位置

泛型接口

泛型应用在接口上

interface Identities<V, M> {
  value: V,
  message: M
}
let ident: Identities<number,string> = {
    value: 123,
    message: '123'
}
泛型函数

泛型应用在函数上

function id<T, U>(arg1: T, arg2: U): T {
  return arg1;
}
//调用时传入相应类型,不传ts会根据传入参数进行类型推断
console.log(id<string,number>('1',3)) // "1"
console.log(id('1',3)) // "1"
泛型约束

一般通过extends方式实现泛型约束

interface Person {
  name:string;
  age:number;
}
function student<T extends Person>(arg:T):T {
  return arg;
}
student({name:'lili'});//类型 "{ name: string; }" 中缺少属性 "age",但类型 "Person" 中需要该属性
student({ name: "lili" , age:'11'});//不能将类型“string”分配给类型“number”
student({ name: "lili" , age:11});

其他

keyof

该操作符用于获取对象类型的所有键,展开为联合类型(前提对象是类型,如接口,类,type

type Point = { x: number; y: number };
type P = keyof Point; // 此时的P类型 即为 ‘x’ | ‘y’
type demoType = keyof string // demoType 的类型为"toString" | "charAt" | "charCodeAt" ….
typeof

该操作符可以用来获取一个变量或对象的类型

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

const sem: Person = { name: 'semlinker', age: 33 };
type Sem= typeof sem; // -> Person

const sem2 = {name:’aaa’,age:12}
type Sem2 = typeof sem2// -> {name:string, age:number}

function toArray(x: number): Array<number> {
  return [x];
}

type Func = typeof toArray; // -> (x: number) => number[]
in

该操作符用来遍历枚举类型

type Keys = "a" | "b" | "c"

type Obj =  {
  [p in Keys]: any
} // -> { a: any, b: any, c: any }
infer

该操作符在有 条件类型extends 子语句中,允许出现 infer 声明,它会引入一个待推断的类型变量。
这个推断的类型变量可以在有条件类型的 true 分支中被引用。

我的理解就是用 infer 定义一个类型变量 接收一个类型 然后用此类型去判断操作

下面通过TypeScript中内置工具类型 ReturnType 理解 infer

ReturnType<T> – 获取函数返回值类型。

// 此工具类型在ts中的用法
const add = (x:number, y:number) => x + y
type t = ReturnType<typeof add> // type t = number

//ReturnType 工具函数的实现源码
/**
 * Obtain the return type of a function type
 */
type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any

再来看 ReturnType 的实现:如果 T 满足约束条件(...args: any) => any,并且能够赋值给(...args: any) => infer R,则返回类型为 R,否则为 any 类型。

tsconfig.json

tsconfig.json 是 TypeScript 项目的配置文件。

tsconfig.json 包含 TypeScript 编译的相关配置,通过更改编译配置项,我们可以让 TypeScript 编译出 ES6、ES5、node 的代码。

使用命令生成
tsc --init

重要字段

  • files - 设置要编译的文件的名称;
  • include - 设置需要进行编译的文件,支持路径模式匹配;
  • exclude - 设置无需进行编译的文件,支持路径模式匹配;
  • compilerOptions - 设置与编译流程相关的选项。

compilerOptions 选项

{
  "compilerOptions": {

    /* 基本选项 */
    "target": "es5",                       // 指定 ECMAScript 目标版本: 'ES3' (default), 'ES5', 'ES6'/'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'
    "module": "commonjs",                  // 指定使用模块: 'commonjs', 'amd', 'system', 'umd' or 'es2015'
    "lib": [],                             // 指定要包含在编译中的库文件
    "allowJs": true,                       // 允许编译 javascript 文件
    "checkJs": true,                       // 报告 javascript 文件中的错误
    "jsx": "preserve",                     // 指定 jsx 代码的生成: 'preserve', 'react-native', or 'react'
    "declaration": true,                   // 生成相应的 '.d.ts' 文件
    "sourceMap": true,                     // 生成相应的 '.map' 文件
    "outFile": "./",                       // 将输出文件合并为一个文件
    "outDir": "./",                        // 指定输出目录
    "rootDir": "./",                       // 用来控制输出目录结构 --outDir.
    "removeComments": true,                // 删除编译后的所有的注释
    "noEmit": true,                        // 不生成输出文件
    "importHelpers": true,                 // 从 tslib 导入辅助工具函数
    "isolatedModules": true,               // 将每个文件做为单独的模块 (与 'ts.transpileModule' 类似).

    /* 严格的类型检查选项 */
    "strict": true,                        // 启用所有严格类型检查选项
    "noImplicitAny": true,                 // 在表达式和声明上有隐含的 any类型时报错
    "strictNullChecks": true,              // 启用严格的 null 检查
    "noImplicitThis": true,                // 当 this 表达式值为 any 类型的时候,生成一个错误
    "alwaysStrict": true,                  // 以严格模式检查每个模块,并在每个文件里加入 'use strict'

    /* 额外的检查 */
    "noUnusedLocals": true,                // 有未使用的变量时,抛出错误
    "noUnusedParameters": true,            // 有未使用的参数时,抛出错误
    "noImplicitReturns": true,             // 并不是所有函数里的代码都有返回值时,抛出错误
    "noFallthroughCasesInSwitch": true,    // 报告 switch 语句的 fallthrough 错误。(即,不允许 switch 的 case 语句贯穿)

    /* 模块解析选项 */
    "moduleResolution": "node",            // 选择模块解析策略: 'node' (Node.js) or 'classic' (TypeScript pre-1.6)
    "baseUrl": "./",                       // 用于解析非相对模块名称的基目录
    "paths": {},                           // 模块名到基于 baseUrl 的路径映射的列表
    "rootDirs": [],                        // 根文件夹列表,其组合内容表示项目运行时的结构内容
    "typeRoots": [],                       // 包含类型声明的文件列表
    "types": [],                           // 需要包含的类型声明文件名列表
    "allowSyntheticDefaultImports": true,  // 允许从没有设置默认导出的模块中默认导入。

    /* Source Map Options */
    "sourceRoot": "./",                    // 指定调试器应该找到 TypeScript 文件而不是源文件的位置
    "mapRoot": "./",                       // 指定调试器应该找到映射文件而不是生成文件的位置
    "inlineSourceMap": true,               // 生成单个 soucemaps 文件,而不是将 sourcemaps 生成不同的文件
    "inlineSources": true,                 // 将代码与 sourcemaps 生成到一个文件中,要求同时设置了 --inlineSourceMap 或 --sourceMap 属性

    /* 其他选项 */
    "experimentalDecorators": true,        // 启用装饰器
    "emitDecoratorMetadata": true          // 为装饰器提供元数据的支持
  }
}



到这里就结束了,后续还会更新 vue 系列相关,还请持续关注!
感谢阅读,若有错误可以在下方评论区留言哦!!!

111

推荐文章👇
ts保姆级教程,别再说你不会ts了
你不知道的 TypeScript 泛型(万字长文,建议收藏)
接近天花板的TS类型体操,看懂你就能玩转TS了
TypeScript中的never类型具体有什么用?
理解 TypeScript 类型收窄

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值