TS学习笔记(入门级别推荐)---原创笔记~

师从尚硅谷教学~

ts官网学习:TypeScript: JavaScript With Syntax For Types.

中文官网:文档简介 · TypeScript中文网 · TypeScript——JavaScript的超集

菜鸟教程:TypeScript 教程 | 菜鸟教程

尚硅谷视频: 尚硅谷TypeScript教程(李立超老师TS新课)_哔哩哔哩_bilibili

掘金TS史上最强学习入门文章:2022 typescript史上最强学习入门文章(2w字) - 掘金

推荐学习网址:TypeScript 入门教程

一、TS 初识

1.1、ts介绍

1、微软开发的一款开源的编程语言
2、是JavaScript的超集,遵循最新的ES6、ES5规范。typescript扩展了JavaScript的语法
3、本质上添加了可选的静态类型和基于类的面向对象编程,通俗的理解为JavaScript的一个特殊版本,其语法规范严谨,适用于开发大型项目应用
4、谷歌也在大力支持typescript的推广,谷歌的angular2.x就是基于typescript
5、最新的vue、react也集成typescript
6、nodeJS框架的Nextjs、midway中用的就是typescript

1.2、ts 开发环境搭建及自动编译

1、全局安装,
   npm i typescript -g
2、运行ts,之后会把ts文件编译为js文件
   tsc demo.ts
3、自动编译配置及运行
   ① tsc --init,创建tsconfig.json文件
   ② 在tsconfig.json中,加入 "outDir": "./js",
   ③ tsc -p tsconfig.json --watch;自动编译生效;

二、TS 中的类型

*** 图解

 

1.1、 any 类型

1. any 表示的是任意类型,一个变量设置类型为 any 后相当于对该变量 关闭了TS的类型检测;
  ***使用TS 的时,不建议使用any类型,
  例:let d:ang;❌不建议;
2. 声明变量如果不指定类型,则TS 解析器会自动判断变量的类型为 any,(隐式的any)
  let d;
  d = 10;  //d 的隐式类型为any

1.2、 unknow 表示未知类型的值

1. unknow 实际上就是一个类型安全的any类型;
2. unknow 类型的变量,不能直接赋值给其他变量;
3. any类型会影响其他变量类型的规定,未知变量类型是使用unknow;
例:
  let e: unknow;
  e = 10;
  e = 'hello';
  e = true;
4. 如果需要变量赋值,可以使用 if 来判断是否是此类型,进而赋值
  if(typeof e === 'string'){
     s = e
  }
5. 类型断言,可以用来告诉解析器变量的实际类型
/*  语法:
       变量 as 类型;
       <类型>变量
*/
 s = e as string;
 s = <string>e;

1.3、 函数类型的定义、函数结构类型声明;

1. void 用来表示空,以函数为例,就是表示没有返回值的函数
   function fn(): void{
   }
2. never 表示永远不会返回结果
   function fn2(): never{
     throw new Error('报错了');
   }
   
3. 设置函数结构的类型声明:
   语法:(形参:类型,形参:类型...) => 返回值
  let d:(a: number,b: number) => number;  //指定义一个类型,参数类型都为number,函数返回值也是number;
  例:相当于;
     d = function (n1: string,n2: string): number{
        return 10;
     }

1.4、 对象 object 的类型定义

1. // object 表示一个js对象,❌,一般不使用object来约束类型,js中一切皆对象,无法约束;
let a: object;
a = {};
a = function(){ }
​
2. 约束对象类型的正确做法
// {} 用来指定对象中可以包含哪些属性;
// 语法: {属性1:属性值1,属性2:属性值2,...}
// 在属性名后边加上?,表示属性是可选择的;
例:
   let b: {name: string,age?: number};  //表示约束变量b 的类型为对应name、age且age字段是可选择的;
   b = {name: '孙悟空',age:18 };
   
3. 约束一个变量,固定一个字段属性,其他属性可选;
  // [propName: string]: any 表示任意类型的属性;
  let c: {name: string, [propName: string]: any};
  c = {name:'唐僧',age: 18,gender: '男'}

1.5、数组的类型定义

1. 语法定义
   类型[],
   Array<类型>
 // string[] 表示字符串数组
 let e: string[];
 e = ['a','b','c'];
 // number[] 表示数值数组;
  let f: number[];
  或
    let g: Array<number>;
    g = [1,2,3];

1.6、 元组类型的定义

1. 元组,元组就是固定长度的数组
    语法:[类型,类型,类型...]
2. 例:
   let h: [string,number];
   h = ['hello',123];

1.7、enum 枚举类型定义

// 定义枚举类型
enum Gender{
    Male,
    Female
 }

let i: {name: string,gender: Gender};
i = {
    name: '孙悟空',
    gender:Gender.Male  // 'male'
}
console.log(i.gender === Gender.Male);  //true

1.8、类型的别名

type myType = 1 | 2 | 3 | 4 | 5; // | 或的意思
let k: myType;
let l: myType;
let m: myType;
// 此时,k、l、m可以且必须是1-5的值;

二、TS 中编译选项

2.1、 tsconfig.json文件

1. tsconfig.json 是ts编译的配置文件,ts编译器可以根据配置信息对代码进行编译;
  'include' 用来指定哪些ts文件需要被编译
     路径: ** 表示任意目录
           * 表示任意文件
  'exclude'  不需要被编译的文件目录
     默认值:['node_modules','bower_compoents','json_packages']
2.  "include":[
     "./src/**/*",   //表示src文件夹下的所有文件都需要编译
  ]
  
3. extends,
   定义被继承的配置文件
 示例: 'extends':'./configs/base';
 * 上述示例中表示,当前配置文件中会自动包含config目录下base.json文件中的所有配置信息;
4. files
  * 指定被编译的文件列表,只有需要编译的文件少的时候才会使用到;
  示例:
     "files":[
        "core.ts",
        "sys.ts",
        ...
     ]   //此时列表中的ts文件将会被编译

2.2、配置中的 compilerOptions

** 编译选项是配置文件中非常重要也是比较复杂的配置选项;
   在compilerOptions中包含多个子选项,用来完成对编译的配置;
 1. target 用来指定ts 被编译为 ES的版本
   "target":"es2016",  //可选项,es3,es5,es6,es2015.....
 2. module 指定要使用的模块化规范
   "module": "es2015",  //可选值 'none','commonJs','amd','es6',....
 3. lib用来指定项目中使用的库
   "lib": ["es6","dom"]
  可选值,.....
 4. outDir 用来指定编译后文件所在的目录
   "outDir": "./dist",
 5. outFile,将代码合并为一个文件
   设置outFile后,所有全局作用域中的代码会合并到同一个文件中,
   "outFile": "./dist/app.js",
 **一般不使用合并的选项,会后续ts结合打包工具webpack来实现编译打包;

2.3、 compilerOptions中的严格检查

1. 是否编译js文件
   "allowJs": true,
2. 检查js代码是否符合语法规范,默认是false
   "checkJs":true,
3. 是否移除注释
   "removeComments":true,
4. 只执行编译,不生成编译后的文件
   "noEmit":false,
5. 当有错误时,不生成编译后的文件
   "noEmitOnError":true

***********是否开启严格模式***************
1. 开启严格模式的总开关,开启后其他项均为true;如果需要单独关闭,单独指定false
  "strict":true,
2. 用来设置编译后的文件是否使用严格模式,默认false
  "alwaysStrict":true
3. 不允许出现隐式的 any 类型
  "noImplicitAny":true
4. 不允许不明确类型的 this
  "noImplicitThis":true
5. 严格的检查空值
  "strictNullChecks":true

***************示例:解决出现空值后的报错***************
 let box1 = document.getElementById('box1');
// box1 的值可能出现null的情况;
//解决
① 条件判断解决
if(box1 !== null){
    box1.addEventListener('click',function(){
        alert('hello ts')
    })
}
② 问号方法
box1?.addEventListener('click',function(){
        alert('hello ts')
    })

三、使用webpack结合ts打包

3.1、 基本使用步骤

1. npm init 项目初始化生成package.json文件;
2. 下载安装对应的包文件
   cnpm i -D webpack webpack-cli typescript ts-loader
3. 项目根目录创建webpack.config.js配置文件
// 引入一个包
const path = require('path');

// webpack中的所有配置信息都应该写在module.exports中
module.exports = {
    // 指定入口文件
    entry: "./src/index.ts",

    // 指定打包文件所在的目录
    output: {
        path: path.resolve(__dirname,'dist'),
        // 打包后文件的位置
        filename: 'bundle.js'
    },

    // 指定webpack 打包时,使用的模块
    module: {
      //指定要加载的规则
      rules: [
        {
            // test指定的是规则生效的文件
            test: /\.ts$/,
            // 要使用的loader加载器
            use: 'ts-loader',
            // 要排除的文件
            exclude: /node-modules/
        }
      ] 
    }
}

4. 根目录创建tsconfig.json配置文件
   {
    "compilerOptions": {
        "module": "ES2015",
        "target": "ES2015",
        "strict": true
     }
   }

5. 在package.json中配置webpack打包选项build;
   "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack"
  },
  
6. 此时执行 
  npm run build 就可以执行webpack打包了

3.2、 配置webpack的插件

1. 安装html插件,
  cnpm i html-webpack-plugin
2. // 引入html插件
const HTMLWebpackPlugin = require('html-webpack-plugin');

3. 配置插件,自动生成index.html文件
// 配置webpack插件,可以在dist文件下自动生成index.html文件
module.exports = {
  plugins: [
        new HtmlWebpackPlugin(),
    ]
 }

4. 加入配置文件 修改生成的html文件的标题以及其他
    plugins: [
        new HtmlWebpackPlugin({
            title: "这是一个自定义title"
        }),
    ]
    
5. 使用index.html模板文件
   在src文件下定义一个模板html文件;
  new HtmlWebpackPlugin({
            // title: "这是一个自定义title"
            template: './src/index.html'
        }),
  
6. 配置dev-server 自动编译加载浏览器
  cnpm i -D webpack-dev-server
  *在package.json文件下scripts下定义"start"
  
7. 引入clean插件,重新构建前先删除dist文件,再次构建
cnpm i clean-webpack-plugin
// 引入clean插件
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
 plugins: [
        new CleanWebpackPlugin(),
        new HtmlWebpackPlugin({
            // title: "这是一个自定义title"
            template: './src/index.html'
        }),
    ]
    
8.  webpack用来设置引用模块。不配置打包会报错
     // 用来设置引用模板
    resolve:{
        extensions: ['.ts','.js']
    }

3.3、配置Bebal插件,来实现ts的兼容性

1. 安装 插件包
   cnpm i -D @babel/core @babel/preset-env babel-loader core-js
2. 添加配置项
   use: [
                // 配置babel,指定加载器
                {
                  loader:"babel-loader",
                  //设置babel
                  options: {
                    // 设置预定义的环境
                    presets:[
                        [
                            //指定环境插件
                            "@babel/preset-env",
                            // 配置信息
                            {
                                // 要兼容的目标浏览器
                                targets:{
                                    "chrome":"58",
                                    "ie":"11"
                                },
                                // 指定corejs的版本
                                // 兼容一些高级语法,如promise在ie中没有
                                "corejs":"3",
                                // 使用corejs的方式 "usage" 表示按需加载
                                "useBuiltIns":"usage"
                            }
                        ]
                    ]
                  }   
                },
                'ts-loader',
            ],

3. 默认webpack 的语法为箭头函数打包,支持ie,需要修改配置项
    output: {
        // 告诉webpack不使用箭头函数,来实现ie浏览器的兼容
        environment:{
            arrowFunction: false,
                const: false
        }
    },

3.5、完整webpack.json配置文件,TS部分

// 引入一个包
const path = require('path');
// 引入html插件
const HtmlWebpackPlugin = require('html-webpack-plugin');
// 引入clean插件
const { CleanWebpackPlugin } = require('clean-webpack-plugin');

// webpack中的所有配置信息都应该写在module.exports中
module.exports = {
    // 指定开发还是生产模式
    mode: 'development',
    // 指定入口文件
    entry: "./src/index.ts",

    // 指定打包文件所在的目录
    output: {
        path: path.resolve(__dirname,'dist'),
        // 打包后文件的位置
        filename: 'bundle.js',

        // 告诉webpack不使用箭头函数,来实现ie浏览器的兼容
        environment:{
            arrowFunction: false
        }
    },

    // 指定webpack 打包时,使用的模块
    module: {
      //指定要加载的规则
      rules: [
        {
            // test指定的是规则生效的文件
            test: /\.ts$/,
            // 要使用的loader加载器
            use: [
                // 配置babel,指定加载器
                {
                  loader:"babel-loader",
                  //设置babel
                  options: {
                    // 设置预定义的环境
                    presets:[
                        [
                            //指定环境插件
                            "@babel/preset-env",
                            // 配置信息
                            {
                                // 要兼容的目标浏览器
                                targets:{
                                    "chrome":"58",
                                    "ie":"11"
                                },
                                // 指定corejs的版本
                                // 兼容一些高级语法,如promise在ie中没有
                                "corejs":"3",
                                // 使用corejs的方式 "usage" 表示按需加载
                                "useBuiltIns":"usage"
                            }
                        ]
                    ]
                  }   
                },
                'ts-loader',
            ],
            // 要排除的文件
            exclude: /node-modules/
        }
      ] 
    },

    // 配置webpack插件,可以在dist文件下自动生成index.html文件
    plugins: [
        new CleanWebpackPlugin(),
        new HtmlWebpackPlugin({
            // title: "这是一个自定义title"
            template: './src/index.html'
        }),
    ],
    // 用来设置引用模板
    resolve:{
        extensions: ['.ts','.js']
    }
}

四、TS中的 面向对象

4.1、面向对象简介

 

4.2、class 类的定义

 

  • 定义类,语法

    class 类名 {
        属性: 类型;
    
        constructor(参数: 类型){
            this.属性 = 参数;
        }
    
        方法名(){
            ...
        }
    }

  • 概念:

// 使用class关键字来定义一个类
/**
 *  对象中主要包含了两个部分内容
 *      1.属性, 分为实例属性和静态属性
 *         ① 直接定义的属性是实例属性,需要通过对象的实例去访问
 *           const per = new Person;
 *           per.name;  来访问;
 *         ② 使用static开头的属性是静态属性&类属性
 *           Person.age直接访问
 *      2.方法
 *        ① 实例方法
 *        ② 静态方法
 */
  • 示例:

class Person {
    // 定义属性,为实例属性,需要new出来之后访问
    // readonly 对属性的只读属性,无法修改
    // readonly name: string = '孙悟空';
    name = '孙悟空' //可以直接定义,默认加入string类型

    // 在属性前使用static关键字可以定义类属性(静态属性),static readonly 静态+只读
    // static readonly age: number = 18;
    static age = 18;

    // 定义方法,实例方法;前面+static是静态方法
    sayHello(){
        console.log('hello 大家好');
    }
    static sayHello(){
        console.log('hello 大家好,static');
    }
}

const per = new Person;
console.log(per.name); 
// per.name = 'jack';
console.log(per.name); 
// 调用实例方法
console.log(per.sayHello());

console.log(per);
// console.log(per.age);
// Person.age = 16; //无法分配到 "age" ,因为它是只读属性。
console.log('Person.age',Person.age);
// 调用静态方法
console.log(Person.sayHello());

4.3、class 类中的构造函数和this

  • constructor 构造函数会在对象创建时调用

  • 调用new函数就相当于调用构造函数constructor

  • 在实例方法中,this就表示当前的实例

  • 可以通过this向新建的对象中添加属性;

class Dog {
//   name: string;
//   age: number;

// constructor  被称为构造函数
// 构造函数会在对象创建时调用
constructor(name: string,age: number) {  //构造函数传参
    // console.log('构造函数执行了'); //调用new函数就相当于调用构造函数constructor
    //  在实例方法中,this就表示当前的实例
    // 在构造函数中当前对象就是当前新建的那个对象
    // 所以,可以通过this向新建的对象中添加属性;
    this.name = name;
    this.age = age;
    // console.log('this',this);  // Dog {}
    
}
  bark(){
    alert('汪汪汪')
  }
}

const dog1 = new Dog('小黑',3);  //调用new函数就相当于调用构造函数constructor
const dog2 = new Dog('小白',5);  

console.log(dog1);
console.log(dog2);

4.4、 类的继承

  • 使用extends关键字,Dog子类继承父类Animal;

  • 继承之后,子类将会拥有父类中所有的属性和方法;

  • 通过继承可以将多个类中共有的代码写在一个父类中;

  • 这样只需要写一次即可让所有的子类都同时拥有父类的属性;

  • 如果需要在子类中添加一些父类中没有的属性或者方法,可以直接加属性和方法就可 *如果在子类中添加了和父类相同的方法,则子类方法会覆盖掉父类的方法 *这种子类覆盖父类方法的形式,我们称为方法的重写;

// 立即执行函数,让变量拥有作用域就可以重复命名了
(() => {
    // 定义一个Animal动物公共类,将dog和cat类中的内容定义在动物类中
    class Animal{
        name: string;
        age: number;
        constructor(name: string,age: number){
            this.name = name;
            this.age = age;
        }
        sayHello(){
            console.log('动物在叫....');
        }
    }

   /* 
      - 使用extends关键字,Dog子类继承父类Animal;
 */

    // 定义一个狗的类
    class Dog extends Animal{
       /*  name: string;
        age: number;
        constructor(name: string,age: number){
            this.name = name;
            this.age = age;
        }
        sayHello(){
            console.log('汪汪汪');
        } */
        // 子类中自己的方法
        run(){
          console.log(`${this.name}在跑...`);
          
        }
    }
    const dog = new Dog('旺财',3)
    console.log(dog);
    dog.run();

    // 定义一个猫的类
    class Cat extends Animal{
        sayHello(){
            console.log('咩咩咩咩');
        }
    }
    const cat = new Cat('tom',6)
    console.log('cat',cat);
    cat.sayHello();
})();

4.5、 类中的super关键字

  • 如果在子类中写了构造函数,在子类构造函数中必须对父类的构造函数进行调用

  • 在子类的构造函数中调用super函数,必须传入父类中的参数,否则语法错误;

// 立即执行函数,让变量拥有作用域就可以重复命名了
(() => {
    // 定义一个Animal动物公共类,将dog和cat类中的内容定义在动物类中
    class Animal{
        name: string;
        age: number;
        constructor(name: string,age: number){
            this.name = name;
            this.age = age;
        }
        sayHello(){
            console.log('动物在叫....');
        }
    }

   /* 
      - 使用extends关键字,Dog子类继承父类Animal;
 */

    // 定义一个狗的类
    class Dog extends Animal{
       /*  name: string;
        age: number;
        constructor(name: string,age: number){
            this.name = name;
            this.age = age;
        }
        sayHello(){
            console.log('汪汪汪');
        } */
        // 子类中自己的方法
        run(){
          console.log(`${this.name}在跑...`);
          
        }
    }
    const dog = new Dog('旺财',3)
    console.log(dog);
    dog.run();

    // 定义一个猫的类
    class Cat extends Animal{
        sayHello(){
            console.log('咩咩咩咩');
        }
    }
    const cat = new Cat('tom',6)
    console.log('cat',cat);
    cat.sayHello();
})();

4.6、TS中的抽象类

  • 以abstract 关键字开头的类,是抽象类

  • 抽象类和其他类区别不大,只是不能用来创建对象

  • 抽象类就是专门用来被继承的类

(() => {
    // 如何定义一个抽象类以及定义抽象方法
    abstract class Animal{
        name: string;
        constructor(name: string){
            this.name = name;
        }
        // 定义一个抽象方法, 方法“sayHello”不能具有实现,因为它标记为抽象。
        abstract sayHello(): void;
    }

    // 继承一个动物类,如果不定义抽象类中是的抽象方法,ts就会报错
    // 非抽象类“Dog”不会实现继承自“Animal”类的抽象成员“sayHello”。
    class Dog extends Animal{
        sayHello(){
            console.log('abstract汪汪汪');
        }
    }
    const dog1 = new Dog('小黑');
    dog1.sayHello();
    // const an = new Animal('小白')  //无法创建抽象类的实例。ts(2511)
})();

5、TS 中的接口 interface&type

  • TS中的接口其实就是指约定一个对象的类型;

  • 定义类时,可以使类去实现一个接口,使用implements关键字

(() => {
    // 什么是接口
    // console.log('接口');
    /* 
      TS中的接口其实就是指约定一个对象的类型;
      定义接口有两种方式:
      ① 使用 type 方式
      ② 使用interface 方式
    */

    //① type 描述一个对象的类型
    type myType = {
        name: string,
        age: number,
    }
    
      /**  ① interface 接口形式描述一个对象的类型
       *   接口用来定义一个类结构,用来定义一个类中应该包含哪些属性和方法
       *   同时接口也可以当成类型声明去使用
       *   接口可以重复名字,重复名字定义的接口字段属性会叠加;
       */
      interface myInterface{
        name: string,
        age: number,
      }
      interface myInterface{
        sex:'男'
      }

      /**  type & interface二者区别
       *   接口可以在定义类的时候去限制类的接口,
       *   接口中的所有属性都不能有实际的值,
       *   接口只定义对象的结构,而不考虑实际的值
       *       在接口中,所有的方法都是抽象方法;
       */

      interface myInter{
        // 都是抽象的
        name: string;
        sayHello():void;
      }

      /**
       *  定义类时,可以使类去实现一个接口
       *     实现接口就是使类满足接口的要求
       *     使用implements关键字来实现接口继承
       */
      // 什么叫接口,只要有看这个接口之后,才可以正常的数据通信;
      // 实际接口就是对我们这个类的限制,制定规范,规定类型;
      class myClass implements myInter{
        name: string;

        constructor(name: string){
          this.name = name;
        }

        sayHello(): void {
          console.log('大家好');
        }
        
      }

    const obj: myInterface = {
        name:'jack',
        age:12,
        sex:'男'
    }
    
    console.log(obj);
    
})();

6、TS 中属性的封装

  • 属性的封装,目的就是让类中的属性访问时更加安全,不能直接修改需要通过类中提供的get和set方法来读取和修改;

  • public 指修饰的属性可以在任意位置访问和(修改) 是默认值

  • private 私有属性,私有属性只能在类内部访问(修改)

  • protected 受保护的属性,只能在当前类和当前类的子类中使用

(() => {
    // 属性的封装
    // 定义一个人的类
    class Person{
      // TS 可以在属性前添加属性的修饰符,来限制属性的访问以及修改
      /**
       *   public 指修饰的属性可以在任意位置访问和(修改) 是默认值
       *   private 私有属性,私有属性只能在类内部访问(修改)
       *      ---通过在类中添加方法,使得私有属性可以被外部访问
       *   protected 受保护的属性,只能在当前类和当前类的子类中使用
       */
       private _name: string;
       private _age: number;

      constructor(name: string,age: number){
         this._name = name;
         this._age = age;
      }

      /* 第二种方法,使用类中自带的属性存取器来设置访问和修改属性的方法
           getter 方法用来读取属性
           setter 方法用来设置属性
               ------- 它们被称为属性的存取器
       */
      // TS 中设置getter方法的方式
      get name(){
        console.log('get name()执行了');
        return this._name
      }
      // TS 中设置setter方法的方式
      set name(value: string){
        // console.log('set name()执行了');
        this._name = value;
      }
      get age(){
        return this._age
      }
      set age(value: number){
        if(value < 0) return;
        this._age = value;
      }

      // // 定义方法,用来获取name属性
      // getName(){
      //   return this._name;
      // }

      // // 定义方法,用来设置name属性
      // setName(value: string){
      //   this._name = value;
      // }

      // // 定义方法访问age属性
      // getAge(){
      //   return this._age;
      // }
      // // 定义方法修改age;
      // setAge(value: number){
      //   // 修改前就可以做判断,如果传入的值是负数,我们将不做任何修改
      //   if(value < 0) return;
      //   this._age = value
      // }

    }

    // 实例化一个Person类
     const per = new Person('孙悟空',18);

     /**
      * 一、现在属性是在对象中设置的,而且可以任意的被修改,
      *   属性可以任意被修改将会导致对象中的数据变得非常不安全,所以我们要解决这个问题;
      * 二、通过在class类内部设置访问和修改属性的方法,来间接安全的操作类中的属性,设置set和get方法;
      * 
      */
    //  调用类中定义的方法,来访问或者修改name属性
      // console.log(per.getName());
      // per.setName('jack');
      // console.log(per.getAge());
      // per.setAge(-33)  //传入的是负数,无法修改age值,达到我们需要的效果
      
      // per._name = 'jack';  
      // per._age = -33;  属性“_age”为私有属性,只能在类“Person”中访问。

      // 通过getter方法设置的方法,可以直接使用per.name,这句实际是在执行getter设置的方法,不是直接访问的属性
      console.log(per.name);
      per.name = 'jack';
      console.log(per.age);
      per.age = -33;
      
      console.log('per:',per);
      
      /* 三、protected 受保护的属性 */
      class A{
        protected num: number;
        constructor(num: number){
          this.num = num;
        }
      }

      class B extends A{
        test(){
          console.log(this.num);
        }
      }
      const b = new B(123);
      // b.num = 33;  //属性“num”受保护,只能在类“A”及其子类中访问。

      /* 四、定义类中属性的简写方式 */
      class C{
        // 可以直接将属性定义在构造函数中
        constructor(public name: string,public age: number){

        }
      }
      /* 上述简写形式等价于下方代码 */
   /*    class C{
        name: string;
        age: number;
        constructor(name: string,age: number){
           this.name = name;
           this.age = age;
        }
      } */
      const c = new C('wangwu',12);
      console.log('C',c);
})();

7、TS 中的泛型

  • 泛型的作用就是在我们对类型不明确的时候,给我们创造一个变量,用这个变量来表示变量的类型,来达到约束类型的效果;

  • 一、在定义函数或是类时,如果遇到类型不明确时,就可以使用泛型

  • 二、泛型可以同时指定多个

  • 三、T extends Inter 表示泛型必须是Inter的实现类(子类)

(() => {
    // TS中的泛型
    // 作用:是在我们对类型不明确的时候,给我们创造一个变量,用这个变量来表示变量的类型,来达到约束类型的效果
    
    /* function fn(a: any): any{ //不确定a和fn返回值的类型,使用any可以解决问题,但是我们前面说过指定any类型的话会让ts失去类型的判断,所以这样做是❌
        return a;
    } */

    /**
     *   一、在定义函数或是类时,如果遇到类型不明确时,就可以使用泛型
     */
    function fn<T>(a: T): T{
        return a;
    }
    // 可以直接调用具有泛型的函数
    let result = fn(10); // 不指定泛型,TS可以自动对类型进行推断;但有时候逻辑复杂时,也需要我们去指定泛型
    console.log(result); //let result: number
    // 指定泛型
    let result2 = fn<string>('hello,泛型');
    console.log(result2);

    /* 二、泛型可以同时指定多个 */
    function fn2<T, K>(a: T,b: K):T{
        console.log(b);
        return a;
    }
    // 调用多个泛型的函数
    fn2<number, string>(999,'www');
    console.log(fn2<number, string>(999,'www'));

    /* 三、T extends Inter 表示泛型必须是Inter的实现类(子类) */
    interface Inter{
        length: number;
    }
    function fn3<T extends Inter>(a: T): number{
        return a.length;
    }
    // fn3([])  此处传入的参数必须要有length属性才可以,也就是说必须是Inter的实现类

    class MyClass<T>{
        name: T;
        constructor(name: T){
            this.name = name;
        }
    }

    const mc = new MyClass<string>('孙悟空');
    console.log('mc:',mc);
})();

五、 TS案例-------贪吃蛇小游戏

  • 项目源码

略~

<think>好的,我需要帮助用户寻找TypeScript相关的学习笔记和资料。首先,根据用户提供的引用内容,已经有几个资源被提到了,比如阮一峰的《TypeScript 入门教程》和TypeScript-Compiler-Notes项目。我需要整理这些信息,并可能补充其他常见的优质资源。 首先,检查用户提供的引用。引用[1]提到了个人笔记和阮一峰的教程,引用[2]是TypeScript编译器笔记的项目,引用[3]是安装TypeScript的方法,引用[4]涉及类型别名和编译选项。用户可能想要更多的学习资料,所以需要将这些已有的内容组织起来,并添加一些其他推荐,比如官方文档、实践项目、社区资源等。 接下来,要确保回答符合系统级指令,比如使用正确的中文和LaTeX格式。不过当前问题主要涉及学习资料,可能不需要数学公式,但如果有相关内容,需要正确应用格式。例如,在解释类型别名时,如果提到类型联合,可以用$type\ A = string\ |\ number$这样的行内公式,但根据用户提供的引用,现有的例子已经足够,可能不需要额外添加。 然后,生成相关问题。根据用户的问题,相关问题应该围绕学习资料、教程、安装配置、进阶内容等。例如,如何安装TypeScript推荐的学习路径,如何参与开源项目等。 需要确保回答结构清晰,分点列出推荐的资料,每个点简要说明内容和获取方式,并在引用处添加标识。同时,补充其他资源时,应确保来源可靠,比如官方文档、知名社区的教程等。 最后,检查是否有遗漏的信息,比如用户可能需要的安装步骤、配置编译选项的方法,这些在引用[3]和[4]中已经提到,可以进一步扩展说明。 总结步骤: 1. 整理用户提供的引用中的资源,明确每个引用的内容。 2. 补充其他常见的TypeScript学习资源,如官方文档、进阶教程、实践项目。 3. 结构化回答,分点列出资源,每个点包含名称、简介和引用标识。 4. 生成相关问题,涵盖安装、学习路径、进阶内容等。 5. 确保符合格式要求,正确使用引用标识,避免使用Markdown,用自然的中文表达。</think>根据您的需求,以下是TypeScript相关学习资源的整理推荐: ### 一、基础学习资料 1. **阮一峰《TypeScript 入门教程》** 适合新手的免费在线教程,涵盖基础语法到高级类型系统,提供中文环境友好解释[^1]。例如类型别名的使用: $type\ mytype = string\ |\ number$ 可实现联合类型定义。 2. **TypeScript官方文档** 权威指南,包含最新特性说明和代码示例,推荐作为核心参考资料(官网:[typescriptlang.org](https://www.typescriptlang.org/))。 ### 二、实践与进阶 3. **TypeScript-Compiler-Notes项目** 深入分析TS编译器源码,适合想了解底层实现的开发者,项目地址可访问:[GitCode镜像库](https://gitcode.com/gh_mirrors/ty/TypeScript-Compiler-Notes)[^2]。 4. **编译选项配置** 通过`tsconfig.json`文件配置模块解析策略,例如: $$ { "compilerOptions": { "target": "ES6", "strictNullChecks": true } } $$ 此类配置可提升代码质量[^4]。 ### 三、环境搭建 5. **安装TypeScript** 使用npm全局安装: ```bash npm install -g typescript ``` 安装后通过`tsc --init`生成配置文件[^3]。 ### 四、社区资源 6. **GitHub开源项目** 参与如Vue 3、Ant Design等使用TS的大型项目,学习实际工程应用。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值