【TS学习笔记】基础篇

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


配置环境

(一)安装nodejs(可跳过)

node.js要先下载;直接去官网下载(建议下载稳定版),然后去配置环境就可以了:

nodejs中文网 选择长期稳定版,或根据自己需要,下载(.msi文件点击安装)就可以了

查看nodejs是否安装成功

node -v

在这里插入图片描述

(二)安装nvm(可选择)

参考之前的文章 七、nvm

使用npm全局安装typescript

(三)正式开始

  1. 安装typescript
    控制台输入
npm install -g typescript

输入tsc检查是否安装成功

在这里插入图片描述

  1. 项目初始化-生成package.json
npm init //初始化
//或者使用
npm init -y //默认全部

在这里插入图片描述

如果已经有.ts文件 使用tsc进行编译

tsc XXX.ts
tsc -W //开启监视,每次保存都会自动编译

编译和监听

添加/配置 tsconfig.json

上面说的编译中-W只能监视当前文件,如果想要监视整个目录下的文件,需要在ts配置文件tsconfig.json中添加

{
    "compilerOptions": {
        "outDir": "./dist/",
        "module": "ES6", //模块化规范
        "target": "ES6",
        "strict": true,
        // "jsx": "react"
    },
    "include": [
        "./src/**/*"
    ],
}

之后运行tsc -W就可以监视所有文件下的ts文件.


tsconifg.json文件是ts的配置文件也是可以通过命令生成

tsc --init 

执行命令之后生成的文件内容可以根据自己的需要修改,生成内容如:

在这里插入图片描述


Ts安装依赖(可跳过)

首先确保已经安装了Webpack;
webpack可以将所有代码和可选择的将依赖捆绑成单独的.js文件

npm install -g webpack

添加开发依赖

  1. awesome-typescript-loader 使webpack使用typescript的标准配置tsconfig.json编译ts代码;
  2. source-map-loader 使用ts输出的sourcemap文件告诉webpack何时生成自己的sourcemaps;
npm install --save-dev typescript awesome-typescript-loader source-map-loader

创建tsconfig.json文件
包含输入文件列表和编译选项。在工程根目录下新建文件tsconfig.json

{
    "compilerOptions": {
        "outDir": "./dist/",
        "sourceMap": true,
        "noImplicitAny": true,
        "module": "commonjs",
        "target": "ES6",
    },
    "include": [
        "./src/**/*"
    ],
    "outDir": "./dist",
    "outFile": "./dist/app.js", //文件合并
    "allowJs": true,
    "noEmitOnError": true,
    "alwaysStrict": true,//开启严格模式
}

创建webpack配置文件
在项目根目录下创建webpack.config.js文件

module.exports = {
    entry: "./src/index.tsx",
    output: {
        filename: "bundle.js",
        path: __dirname + "/dist"
    },

    // Enable sourcemaps for debugging webpack's output.
    devtool: "source-map",

    resolve: {
        // Add '.ts' and '.tsx' as resolvable extensions.
        extensions: [".ts", ".tsx", ".js", ".json"]
    },

    module: {
        rules: [
            // All files with a '.ts' or '.tsx' extension will be handled by 'awesome-typescript-loader'.
            { test: /\.tsx?$/, loader: "awesome-typescript-loader" },

            // All output '.js' files will have any sourcemaps re-processed by 'source-map-loader'.
            { enforce: "pre", test: /\.js$/, loader: "source-map-loader" }
        ]
    },

    // 当导入路径与以下其中一个匹配的模块时,只需假设存在相应的全局变量并使用该全局变量即可。
//这一点很重要,因为它允许我们避免捆绑所有的依赖项,从而允许浏览器在构建之间缓存这些库。
    externals: {//命名空间
       // "react": "React",
        //"react-dom": "ReactDOM"
    },
};

一、类简介

对象中主要包含两个部分: 属性、方法

(一) 属性

1.实例属性 通过定义实例对象进行调用 如name属性;
2.静态属性 通过类调用 如 Person.age

class Person {
    // 定义实例属性 == 可被修改
    name: string = '张三';
    // 定义静态属性
    static age: number = 18;
    readonly gender: string = '男';//只读属性
}

const per = new Person();//创建实例对象
console.log(per.gender);
console.log(per.name);//张三

console.log(Person.age)//调用静态属性

per.name = '李四';
console.log(per.name);//调用实例属性 李四

(二) 方法

创建方法

 // 定义方法
    // 类方法 可直接通过类调用
    static run() {
        console.log("I can run");
    }
    //实例方法
    eat() {
        console.log("I can eat");
    }

调用方法

// 调用类方法
Person.run();//I can run
// 调用实例方法
per.eat();//I can eat

二、构造函数和this

构造函数,在对象创建时被调用
构造函数中 this表示当前实例
当前对象 == 当前新建的对象 谁new的就是谁

//构造函数  == 在对象创建时被调用
    constructor(){
        console.log("constructor is run")
        console.log(this);//this 表示当前的实例
    }

在这里插入图片描述

	可以通过this 在新建的对象中添加属性

在这里插入图片描述

三、继承

使用继承后,子类继承所有父类的方法和属性

	可以将多个类中的共有代码,写在同一个父类中,所有的子类可以同时拥有父类中的属性和方法.
	可以在不修改原来代码的基础上,增加新的方法;
方法重写-->如果在子类中增加与父类相同的方法名,子类会覆盖父类的方法;

继承演示
方法重写
方法重写

四、super关键字

super代表当前类的父类

在这里插入图片描述

五、抽象类

abstract 表示抽象
抽象类中不能创建实例对象;只能被继承
抽象类中可以添加抽象方法
抽象方法没有方法体
在继承的时候必须实现抽象类中的抽象方法;

抽象类和抽象方法示例

六、接口

接口定义了一个规范,是对类的一种规范限制;没有实际值;实现接口必须满足接口中的类和方法

	接口用来定义一个类结构;
	定义一个类中应该包含哪些属性和方法;
	接口也可以被当成类型声明使用
	接口在被定义类的时候限制类的结构;
	接口的所有属性都不能有实际的值,只能定义对象的结构,而不考虑实际的值;
	接口中的所有方法,都是抽象方法;

对象和接口的区别

  1. 对象声明,在方法中只能声明一次,接口可以被定义多个

声明对象类型
在这里插入图片描述
定义类时实现接口
在这里插入图片描述

七、属性的封装

	ts可以在属性前添加属性修饰符
	public 公共的 可以在任何位置访问(修改)  默认(大家)
	private 私有的 只能在类内部访问(自己)
	protected 受保护的 可以在当前类中和在被继承的时候被访问(自己和子类)

为了防止数据被恶意修改,属性被封装到 存储器里(getter setter);
因为private属性是私有的不能被类以外的地方调用;但是可以通过存储器被暴露出去.
此时可以根据自己的需求,通过get set对方法中的属性暴露.为后续修改提供限制进行修改;

class Cup {
  private owner: string; //只能在类中被调用
  private name: string;

  constructor(name: string, owner: string) {
    this.name = name;
    this.owner = owner;
  }
 /** 属性存储器 */
  //读取属性
  getName() {
      return this.name;
  }
  // 设置属性
  setName(value: string) {
      this.name = value;
  }
}
const cup = new Cup('早餐杯', '可爱型');
console.log(cup.getName())//早餐杯
cup.setName('水杯');
console.log(cup.getName())//水杯

上述方式增加了书写代码的数量,每一次都需要带方法名.
为了使用户体验更加良好,ts提供了一种特有的方式进行封装
方法不同,定义和调用的方式也不同,注意区分

  private _owner: string;
  private _name: string;

  constructor(name: string, owner: string) {
    this._name = name;
    this._owner = owner;
  }
  get owner() {
    return this._owner;
  }
  set owner(value: string) {
    this._owner = value;
  }
  get name() {
    return this._name;
  }
  set name(value: string) {
    this._name = value;
  }
  
const cup = new Cup('早餐杯', '可爱型');
console.log(cup.name)//早餐杯
cup.name = '水杯';//赋值
console.log(cup.name)//水杯

注意 get后的方法名不能和属性名重名

属性少的类,可以将属性直接写道构造函数中;节省书写步骤.

//可以直接将属性写在构造函数中
class C {
  constructor(public name: string, public gender: string) { }
}
const c = new C('张三', '男');
console.log(c);
console.log(c.name)//张三

在这里插入图片描述
上述方法等价于

 // 一个是在原型上添加方法,一个是在原型上定义属性; 属性和get方法不能崇明
  name: string;
  gender: string;
  
  constructor(name: string, gender: string) {
    this.name= name;
    this.gender= owner;
  }

八、泛型

定义函数/类时,如果类型不明确,可以使用泛型.

定义泛型<*> *可以是任何字母,表示任意类型

定义一个参数类型:

//定义泛型<T> a的类型是T :T(返回值是T类型)
function fn<T>(a: T): T {
  return a;
}

fn(10);//利用函数的自动推断,此时T指number型
fn<string>('hello')//指定泛型;当类型复杂,可以指定

定义多个参数类型

// 泛型可以同时指定多个
function fn2<T, K>(a: T, b: K): T {
  console.log(b)
  return a;
}

fn2<number, string>(12, '天天') //打印出天天

泛型可以继承接口实现类

interface lent {
  length: number;
}
// T extends lent 泛型T必须是lent的实现类(子类)
function fn3<T extends lent>(a:T):number{
	return a.length;
}

fn3('123')
// fn3(123)//会报错->不可转换的参数类型
fn3({ length: 10 })

泛型可以用类定义

class fn4<T>
{
  name: T;
  constructor(name: T) {
    this.name = name;
  }
}
const f4 = new fn4<string>('张安')
console.log(f4.name) //张安

总结

这些是我在跟着网课学的时候自己敲下来的总结笔记,作为自己的笔记记录.如果能帮到你们当然也很好.
如果有什么错误和不足,欢迎补充.
最后的泛型我也是听的一知半解,跟着做了项目也没有用到这个
🕳 在get set中定义的时候 显示说标识符重复

其实很好理解,就相当于说 get 是一种声明说此时是get方法.后面的是方法名称.
比如name在上面已经被定义过了,后面的方法名称写name当然会报错.
get里面return 的值是属性的值就可以了.
所以在get name的方法体中,return的是属性名_name.
好的,让我来回答你关于 TypeScript 中 Symbol 和模块的问题。 首先,Symbol 是 TypeScript 中的一种新的基本数据类型,它可以用来创建唯一的标识符。在 TypeScript 中,Symbol 主要有两种用法: 1. 作为对象属性的键值,用来表示一个对象属性的唯一标识符。 2. 作为一个类的静态属性或方法,用来表示该类的唯一标识符。 下面是一个使用 Symbol 作为对象属性键值的示例: ```typescript const key = Symbol('myKey'); const obj = { [key]: 'value' }; console.log(obj[key]); // 输出'value' ``` 在上面的代码中,我们使用 Symbol('myKey') 创建了一个新的 Symbol,然后将该 Symbol 作为对象 obj 的属性键值,并赋值为'value'。最后,我们通过 obj[key] 的方式来访问该属性,并输出了'value'。 另外,模块是 TypeScript 中的另一个重要概念,它用来组织和管理代码。在 TypeScript 中,模块可以使用 import 和 export 命令来进行导入和导出。下面是一个使用模块的示例: ```typescript // moduleA.ts export const num = 123; // moduleB.ts import { num } from './moduleA'; console.log(num); // 输出123 ``` 在上面的代码中,我们定义了一个名为 num 的常量,并将其导出。然后,在另一个模块中,我们使用 import 命令将 num 导入,并通过 console.log 输出了它的值。 这就是关于 TypeScript 中 Symbol 和模块的简单介绍,希望能对你有所帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值