首页 > 其他分享 >【TypeScript】学习笔记

【TypeScript】学习笔记

时间:2023-01-18 12:05:37浏览次数:53  
标签:TypeScript string power number 笔记 学习 let 类型 name


一. 环境搭建

  1. 安装Node.js
  2. npm i -g typescript
  3. 创建ts文件test.ts,编译:tsc test.ts

二. 基本类型

1. 类型声明

语法:

let 变量:类型;
let 变量:类型=值;
function fn(参数:类型,参数:类型):类型{}

实例:

let myStr: string = "123";
let myNum: number;

console.log(myStr);
myNum = 100;
console.log(myNum);

输出:

var str = "123";//默认编译为ES3版本的JS代码
var num;
console.log(str);
num = 100;
console.log(num);

如果变量的声明和赋值是同时进行的,TS可以自动对变量进行类型检测。

let c = false;
c = 123;//error

如果不需要写明类型就能自动判断,那么我们前面写明的类型限制会显得很鸡肋,反正写不写都一个样。

但是,我们常需要做的类型限制不仅仅只是变量,或者说对变量的限制需求没有那么高,真正高的是函数:

function sum(a,b){
return a+b;
}

如果不做类型检测,若传入的是123以及"456",则不会报错,且输出为“123456”。若结果用到别的地方,则会导致一连串的错误。

function sum(a:number,b:number):number{
return a+b;
}
sum("123",456);//类型“string”的参数不能赋给类型“number”的参数。
sum(123,456,789);//应有 2 个参数,但获得 3 个。
let result = sum(1,2);//悬浮result:let result: number

2. 基本类型

类型

例子

描述

number

1, -33, 2.5

任意数字

string

'hi', "hi", ​​hi​

任意字符串

boolean

true、false

布尔值true或false

字面量

其本身

限制变量的值就是该字面量的值

any

*

任意类型

unknown

*

类型安全的any

void

空值(undefined)

没有值(或undefined)

never

没有值

不能是任何值

object

{name:'孙悟空'}

任意的JS对象

array

[1,2,3]

任意JS数组

tuple

[4,5]

元素,TS新增类型,固定长度数组

enum

enum{A, B}

枚举,TS中新增类型

  • 可以使用字面量进行类型声明
let a:10;//相当于常量
a = 10;//√
a = 11;//不能将类型“11”分配给类型“10”

也可以使用 | 连接多个类型(联合类型)

let b: "male" | "female";
b = "male";
b = "female";
b = "hello"; //不能将类型“"hllo"”分配给类型“"male" | "female"”。

let c: boolean | string;
c = true;
c = "hello";
  • any表示的是任意类型,相当于对该变量关闭了TS的类型检测。
// 显示any
let d:any;
d = 10;
d = "hello";
d = true;
// 隐式any
let dd;
dd = 10;
dd = "hello";
  • unknown表示未知类型(也可以赋值任意值,但是是类型安全的any):
let e:unknown;
e = 10;
e = "hello";

区别:

let s:string;
s = d;//d是any,可以赋值给任意类型
s = e; //e是unkonwn,虽然上面赋值了“hello”,但是类型不匹配。
//不能将类型“unknown”分配给类型“string”。

类型断言:告诉解析器的实际类型。

//(告诉编译器,它就是字符串)
s = e as string;
  • void:用来表示空,没有返回值的函数。
function fn():void{
//return null;
//return undefined;
// no return
}
  • never:表示永远不会返回结果。连undefined都不返回。
function fn2():never{
throw new Error('报错了!')
}
  • object:表一个JS对象
let a:object;
a = {};
a = function(){};//万物皆对象,函数也是对象

{}可以用来指定对象包含哪些属性,属性名后接?,表示属性是可选的。

let b:{name:string,age?:number};
b = {name:'皮卡丘',age:2};
//但是不能额外新增其他的属性
b = {name:'孙悟空',skill:'七十二变'};//error
//不能将类型“{ name: string; skill: string; }”分配给类型“{ name: string; age?: number; }”。
//对象文字可以只指定已知属性,并且“skill”不在类型“{ name: string; age?: number; }”中。

​[propName:String]:any​​可以表示任意类型的属性。​​propName​​可以是任意的内容。

let b:{name:string,[xx:string]:any};
b = {name:'孙悟空',skills:'七十二变'};//√
  • 函数结构的类型声明: (形参:类型,形参:类型)=>返回值
let d:(a:number,b:number)=>number;
  • 数组声明:类型[]Array<类型>
//字符串数组
let strArr:string[];
strArr = ['1','a','c'];
// 数字数组
let numArr:Array[number];
numArr = [1,2,50];

TS除了保留原有的JS类型之外,还额外新增了两种类型:tuple,enum

  • 元组tuple:固定长度的数组。语法:[类型,类型,类型]
let h:[string,string];
h = ['hello'];//error
h = ['hello','123'];
h = ['hello',123];//error
h = ['hello','123','456'];//error
  • 枚举enum:

问题:下面的0和1,别人可能不知道1表示男还是女?

let i:{name:string,gender:0|1};
i={
name:'孙悟空',
gender:1 //'male'
}

使用枚举解决:

enum Gender {
Male = 0,
Female = 1
}
let i:{name:string,gender:Gender};
i={
name:'皮卡丘',
gender:Gender.Male
}
console.log(i.gender === Gender.Male);

&表示同时具有:

let j:{name:string}&{age:number}
j = {name:'皮卡丘',age:1};
let nonsene :{number & string}//毫无意义

​type​​表示类型别名:遇到特别长的声明可以使用这个。

type myType = 1|2|3|4|5
let j:myType
let k:myType
j = 2;
k = 6;//error

三. 编译选项

总不能每次都是手动通过tsc xxx.ts进行编译成js文件吧?

  1. 编译器自动监视ts文件 -w:(watch)监视
tsc test.ts -w
  1. ​tsconfig.json​​:ts编译器的配置文件。文档:https://aka.ms/tsconfig.json

初始化:​​tsc -init​

  • include:指定编译的文件目录
  • exclude:定义需要排除的文件
  • extends:定义被继承的配置文件
  • files:定义编译的文件列表
  • compilerOptions:编译器的选项
  • target:指定ts编译的目标版本。(如果不清楚可填的值,可以填一个错误的,看报错信息)
  • 'es3', 'es5', 'es6', 'es2015', 'es2016', 'es2017', 'es2018', 'es2019', 'es2020', 'es2021', 'es2022', 'esnext'
  • module:指定要使用的模块化的规范。
  • 'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015', 'es2020', 'es2022', 'esnext', 'node12', 'nodenext'
  • lib:用来指定项目中要使用的库
  • outDir:指定编译后的文件所处目录。
  • "./dist"
  • outFile:将代码合并为一个文件。只有amd和system模式(module)支持该模式。不适合模块化。
  • allowJs:是否对JS文件进行编译,默认是false
  • true | false
  • checkJs:是否检查JS代码是否符合语法规范。默认是false。
  • true:若修改为true,则会在js文件里面出现语法检查。
  • removeComments:是否移除注释
  • noEmit:不生成编译后的文件。
  • noEmitOnError:当有错误的时候,不生成编译的文件。
  • 。。。

四. Webpack + TS

(一)基础配置

1. 配置依赖

cnpm i -D webpack webpack-cli typescript 
cnpm i -D html-webpack-plugin ts-loader
cnpm i -D webpack-dev-server
  • webpack脚手架:webpack,webpack-cli
  • ts-loader:加载TS文件内容
  • html-webpack-plugin:生成模板html,自动引入依赖
  • webpack-dev-server:即时更新
  • TS环境:typescript

2. webpack.config.js

新建webpack.config.js,配置如下:

const path = require('path');
const HTMLWebpackPlugin = require('html-webpack-plugin');
// const {CleanWebpackPlugin} = require('clean-webpack-plugin');
module.exports = {
// 入口
entry: "./src/index.ts",
// 输出
output:{
path:path.resolve(__dirname,'dist'),
filename:'bundle2.js',
clean:true,
},
mode:'development',
// 打包使用模块
module:{
//指定加载规则
rules:[
{
test:/\.ts$/,
use:'ts-loader',
//排除文件
exclude:/node-modules/
}
]
},
plugins:[
// new CleanWebpackPlugin(),
new HTMLWebpackPlugin({
// title:'LearningTs',
template:'./src/index.html'
}),
],
// 用来设置引用模块
resolve:{
extensions:['.ts','.js']
}
}

3. tsconfig.json

创建tsconfig.json文件,用于指定ts编译后的内容

{
"compilerOptions": {
"target": "es2015",
"module": "es2015",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": false,
"skipLibCheck": true
}
}

4. 构建指令配置

在package.json中修改script配置,增加build指令以及start指令:

"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build":"webpack",
"start":"webpack serve"
},

此时,通过​​npm run build​​即可看到最简单的构建产物。

(二)清除旧的打包产物

  • 方式一:引入插件
  1. 安装:cnpm i -D clean-webpack-plugin
  2. 引入config
const {CleanWebpackPlugin} = require('clean-webpack-plugin');
  1. 注册plugin
plugins:[ new CleanWebpackPlugin(), ]
  • 方式二:直接在output中增加clean:true的配置项。

五. class

0. 基础使用

回顾并在原本的js-class中体验ts-class的用法。

class Person{
//定义实例对象
name: string = '小智';

//static:定义类属性(静态属性)
static age: number = 18;

//readonly 表示一个只读属性
static readonly skill: string = "eat";

//定义方法,前置static就是类方法
sayHello(){
console.log("Hello");
}
}

1. 构造函数&this

我们通过​​constructor​​构造函数以及​​this​​指向当前对象的实例。

class 皮卡丘{
name:string;
power:number;
kind:string;
constructor(name:string,power:number,kind:string){
this.name = name;
this.power = power;
this.kind = kind;
}
bark(){
alert("皮卡皮卡");
}
}
let pikaqiu = new 皮卡丘('YY的皮卡丘',100,'electricity');
pikaqiu.bark();

2. 继承

还可以通过​​extends​​实现继承。可以在类前面加sealed关键字禁止继承。扩展点:OCP原则。

//父类
class 宝可梦{
name:string;//昵称
power:number;//力量
kind:string;//类别
constructor(name:string,power:number,kind:string){
this.name = name;
this.power = power;
this.kind = kind;
}
bark(){
alert("宝可梦在叫~");
}
}

//子类
class 比雕 extends 宝可梦{
//可以不写,但是如果在子类中写了构造函数,则必须通过super调用父类的构造函数
constructor(name:string,power:number){
super(name,power,'flight');
}
fly(){
console.log(`${this.name}在飞~`);
}
//方法重写
bark(){
console.log("渣渣~喳喳~");
}
}

3. 抽象

  • 抽象类
    上面的宝可梦是一个抽象的概念,我们可以创建比雕,但是不能直接创建宝可梦。所以我们通过abstract关键字来声明这是一个抽象类。
  • 抽象方法
    不同的宝可梦叫声不一样,所以不能直接写出宝可梦的bark具体实现。需要声明它是抽象方法。
abstract class 宝可梦{
//抽象方法只能定义在抽象类,且子类必须对其进行重写。
abstract bark():void;
}

4. 接口

接口是抽象的最高境界,抽到只剩下灵魂了~~

  1. 接口只定义对象的结构,而不考虑实际值。
  • 所有的属性都不能有实际的值。
  • 所有的方法都是抽象方法。
  1. 定义类时,可以使类去实现一个接口。
type myType{
name:string;
sayHello(){
//...
}
}
interface myInterface{
name: string;
sayHello():void;
}
class MyClass implements myInterface{
name: string;
sayHello(){
console.log("大家好");
}
}

5. 属性封装

TS可以在属性前添加属性的修饰符,确保数据更加得安全。

  • public:公有的,修饰的属性可以在任意位置访问修改默认值。(默认修饰符)
  • private:私有属性,只能在类的内部进行访问。通过getter和settter可以被外部访问。

问题:为什么需要设置私有属性,然后再设置getter和setter呢?这不是多此一举吗?

理解:当一个类的属性可以被任意访问的时候,容易埋下隐患。通过getter和setter可以判断修改的值是否有效。

情景:比如宝可梦的力量power需要为正数。后续进行战斗,对方宝可梦的体力基于己方宝可梦的力量值进行扣除。若某处直接将其设置为负数,则会给对方宝可梦增加体力。如果通过setter呢?

(function(){
class 皮卡丘{
public name:string;
private power:number;
constructor(name:string,power:number){
this.name = name;
this.power = power;
}
getPower(){
return this.power;
}
setPower(newPower:number){
if(newPower < 0 || newPower > 100 ) return 'error';
this.power = newPower;
}
//当然,也有语法糖
get name(){
return this.name;
}
set name(value:string){
//judge is Valid ,then
this.name = value;
}
}
})();

除了​​private​​和​​public​​之外,还有protected修饰符。仅限当前类以及子类访问。

class A{
protected num : number;
constructor(num:number){
this.num = num;
}
}
class B extends A{
test(){
console.log(this.num);
}
}

我们可以直接将属性定义在构造函数中

class C{
constructor(public name:string,private age:number){}
}
const c = new C ('xxx',18);

6. 泛型

一个多元方程中的未知数x,只有代入其他具体的值,才能推断出它来。

问题:如果不确定输入的类型,但是要限制输出的类型和输入的类型一样,咋办?

function fn(a:any):any{
return a;
}

标签:TypeScript,string,power,number,笔记,学习,let,类型,name
From: https://blog.51cto.com/u_15941981/6007954

相关文章

  • Django一个“高质量”小白的学习之路
    人类的思维倾向于直白、视觉和线性,还有好奇心,这是祖先遗传下来的思维习惯。如果论结果,显然我是一个计算机学习的失败者。因为我作为一个已经刚到不惑之年的中年男子,还在......
  • 读书笔记:价值投资.05.不为清单(二)
    老巴的教导千万别忘了:不做空,不借钱,不做不懂的东西.04.不要走捷径(fastisslow,快即是慢)其实,价值投资是投资的唯一一条路,不要走捷径,不要相信弯道超车.......
  • VUEX 使用学习四 : action
    转载请注明出处:action用于处理异步任务;action,可以操作任意的异步操作,类似于mutations,但是是替代mutations来进行异步操作的。首先mutations中必须是同步方法,如果使用......
  • typescript中特殊符号(?/!)用法
    1.属性或参数中使用 ?:表示该属性或参数为可选项2. 属性或参数中使用 !:表示强制解析(告诉typescript编译器,这里一定有值),常用于vue-decorator中的@Prop3.变量后使用 !:表......
  • windows10笔记本如何开wifi热点
    很多人在使用windows10系统的笔记本,开启WiFi热点都是提示没有找到支持的无线网卡。不管你是驱动更新,重装,还是怎么操作都是不能用。那么应该如何解决这个问题呢?下面就跟大家......
  • 学习笔记——AOP-代理模式
    2023-01-18一、AOP前奏-代理模式1、手动实现动态代理环境搭建(1)基于接口实现动态代理:JDK动态代理(2)基于继承实现动态代理:Cglib、javassist动态代理2、实现动态代理的步......
  • LESSON ONE : Markdown 语法学习
    Markdown语法学习字体粗体斜体斜体加粗删除线引用引用分割线图片超链接点击跳转到我的博客列表ABC1+点号与空格ABC减号加空格表格......
  • 学习Vuex mutations
     Vuex中store数据改变的唯一方法就是提交 mutations。mutations里面装着一些改变数据方法的集合,这是Vuex设计很重要的一点,就是把处理数据逻辑方法全部放在 mutation......
  • React Hook学习笔记
    函数组件基本使用及点标记组件写法函数组件的基本使用函数组件是比类组件编写起来更简单的一种组件形式,对比如下://类组件classWelcomeextendsReact.Component{......
  • 【笔记】前端人脸检测之clmtrackr.js的使用
    clmtrackr.js使用示例代码html代码:<divclass="video-con"><videoid="video"playsinlineautoplaywidth="300"height="300"></video><canvassty......