TypeScript入门版~适合初学者快速学习。

Posted 1024_Byte

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了TypeScript入门版~适合初学者快速学习。相关的知识,希望对你有一定的参考价值。

前言

大家好,本文是我在学习TypeScript过程中的一些总结。

目前版本仅写到关于typeScript基础使用,模块命名空间修饰符等内容,在总结时总感觉案例有些苍白。我会在后面ts的项目demo中进行总结和输出。
我是通过观看教学视频和ts官方文档的结合进行学习。在学习过程中晦涩难懂的部分,我也会查看一些大佬发出来的经验贴进行吸收。
发出这篇文章的本意是希望能够加深自己的印象,同时能够将自己学习的内容进行一定的输出。
当然我作为一个菜鸡总结的还不是很到位。如果各位大佬发现了问题希望能直言不讳指出来,我会及时改正,谢谢支持。ღ( ´・ᴗ・` )比心

Part 01 - TypeScript

TypeScript微软开发的一门编程语言,是javascript的一个超集。
TypeScript扩展了的语法,所以任何现有的JavaScript程序可以运行在TypeScript环境中。TypeScript是为大型应用的开发而设计,并且可以编译为JavaScript。
TypeScript的学习成本并没有想象中的大。作为渐进式的编程语法,你完全可以前期直接编写JavaScript的代码,之后在通过学习了解一个特性新增一个特性。

Part 02 - 安装TypeScript及基础命令

安装TypeScript

npm i typescrpit --dev

执行ts文件编译为js文件

tsc .\\getingTs.ts

执行配置文件初始化

tsc -- init

中文报错提示

tsc -- locale zh-CN

Part 03 - TypeScript配置文件

tsconfig.json
如果一个目录下存在一个tsconfig.json文件,那么它意味着这个目录是TypeScript项目的根目录。 tsconfig.json文件中指定了用来编译这个项目的根文件和编译选项

目录结构

---- src/ 
    ---- dist/ 
       |---- index.js // 编译后js文件
    |---- index.ts // 整个工具库的入口
    |---- tsconfig.json//配置文件

常用配置项 – 因为太多了因此只列出常用的
详细可查看官方文档
https://www.tslang.cn/docs/handbook/tsconfig-json.html


  "compilerOptions": 
    "target": "ES5",             // 目标语言的版本
    "lib": [ "es5","es2015"],    // 标准库声明
    "module": "commonjs",        // 指定生成代码的模板标准
    "noImplicitAny": true,       // 不允许隐式的 any 类型
    "removeComments": true,      // 删除注释 
    "preserveConstEnums": true,  // 保留 const 和 enum 声明
    "sourceMap": true            // 源代码映射,生成目标文件的sourceMap文件
    "rootDir": "src",            // 入口文件夹
    "rootDirs": ["src","src/class",],   // 设置多个入口文件夹
    "outDir": "dist",            // 编译后输出文件夹
    "strictNullChecks": true,    // 检查变量是否不能为null
    "experimentalDecorators": true      // 支持装饰器特性
  ,
  "files": [   // 指定待编译文件
    "./src/index.ts"  
  ]


Part 04 - TypeScript基础数据类型

TypeScript支持与JavaScript几乎相同的数据类型,此外还提供了实用的枚举类型方便我们使用。

Boolean布尔值类型

const doBoolean: boolean = false; // true

Number数值类型

ts中规定的Number类型除了常数外,NaNInfinity浮点数都是支持的,包含十进制十六进制二进制和八进制的字面量。

const doNumber: number = 1; 
const doNaN: number = NaN;
const doInfinity: number = Infinity;
const doHex: number = 0xf00d

Sring字符串类型

除了可以识别正常的字符串外,模板字符串拼接字符串也都是可以正常使用的,也可以结合其他变量进行定义。

const doString: string = `foo`; 
const testString: string = `foo$doStringand$doNumber + 1`;
const spliceString: string = 'foo'+doString+'and'+doNumber + 1;

Object对象类型

object并非表示普通的对象类型,而是泛指所有非原始类型。
也就是除numberstringbooleansymbolnullundefined之外的类型。

也就意味着当定义为object类型,所有的原始类型都不被指定。

Error: const foo: object = 123; //不能将类型“number”分配给类型“object”。

同时object类型也不单指普通的对象

const foo1: object = function name() ;
const foo2: object = [];
const foo3: object = ;

当然你也可以通过字面量形式去定义对象

注意如果添加了指定的成员,必须要保证一一对应上,既不能多也不能少

const foo4:  a: number; b: string  =  a: 1, b: "1" ;

Array数组类型

有两种方法可以定义数组

方法一:可以在元素类型后面接上 [],表示由此类型元素组成的一个数组

const arr1: number[] = [1, 2];
const arr2: object[] = [, ];
const arr3: any[] = [, function () ];

方法二:可以数组泛型来进行表示

const arr1: Array<string> = ["a", "b"];
const arr2: Array<object> = [, ];
const arr3: Array<any> = [, function () ];

tuple元组类型

元组类型允许表示一个已知元素数量和类型的数组,各元素的类型不必相同。

const tuple: [number, string] = [18, "a"];

但是数组的内的类型和数量必须与指定类型一致,若不一致则会报错。

 const tuple: [number, string] = ["Ethen",18];// Error
 const tuple: [number, string] = [18, "Ethen",'boy'];// Error

enum枚举类型

默认情况下,从0开始为元素编号给成员进行赋值

enum 枚举名称 成员1,成员2,...
enum Family Mom,Father,Me // Mom=0 Father=1 Me=2
enum Color  Red, Green,Blue,

并且枚举数值只作为可读属性在定义后不能进行更改。
而枚举是一种类型,可以作为变量的类型注解

let c: Color = Color.Green; // c=1

当然你也可以手动的指定成员的数值。但是注意如果初始化赋值为字符串类型,其他成员也要进行相应赋值。

enum num 
  one = 1,
  two , //2
  three , //3


Family  
  Mom = 'emily',
  Father='joe' ,
  Me='mark' , 

并且我们可以由枚举的值得到它的名字。 例如,我们知道数值为2,但是不确定它映射到哪个名字,我们可以查找相应的名字。

enum Color Red = 1, Green, Blue
let colorName: string = Color[2]; // Green

Any任意类型

any代表任意类型,也就意味任何类型都可以被指定。同时作为动态类型和js的类型使用是没有任何区别的,也就代表着仍然存在着类型隐患。

因此any类型一般多用于不希望类型检查器对这些值进行检查而是直接让它们通过编译阶段的检查。

例如 :document.getElement JSON.stringfy

const flag: any = 'string'; //number undefined ....

Void无效类型

void它表示没有任何类型,通常用于一个函数没有返回值进行指定。

通常没有任何意义,因为只能赋值为nullundefined(如果设置不能为null则只能赋值undefined)

function void(): void  

    console.log("no return"); 
    


const noTarget: void = undefined;

Never类型

never类型如字面意义表示的是那些永不存在的值的类型。

//当你在函数内部抛出一个异常时,此函数永远不会有返回值,因此定义为Never类型
function error(message: string): never 

  throw new Error(message);
  

Part 05 - TypeScript类型特性

TypeScript除了使用以上类型以外还拥有很多类型的特性。

类型推断

TypeScript里,在有些没有明确指出类型的地方,类型推断会协助你指定变量的类型。

let age = 18; // Number
age = 'string' //Error

当然如果你在声明变量时没有指定任何类型,那他会默认为Any类型,那么后续进行任何赋值操作也都是被认可的

let age        // Any
age = 'string' //true
age = 18       //true

那么还有一种情况,当你在使用引用数据类型时,如:在数组内部使用了多个表达类型。

TypeScript会根据这些表达式的类型来推断出一个最合适的通用类型

let age=[18,'string',null] // (string | number | null)[]

类型断言

当我们在使用TypeScript时你会遇到这么一种情况,你会比程序更了解这个变量的值的类型。

例如:

const tel = [110, 120, 119];
const emergency = tel.find((i) => i ==110 || i==120); // number | undefined

然而在TypeScript推断时会认为undefined的情况,而我们能够确定不会出现,这种情况下通过类型断言这种方式可以告诉编译器没有特殊情况发生。

那通常我们会使用两种方法来定义类型断言

第一种: 通过(xxx as type)

let someValue: any = "this is a string"; 
let strLength: number = (someValue as string).length;

第二种: 通过(<type>xxx)

let someValue: any = "this is a string"; 
let strLength: number = (<string>someValue).length;

这里需要注意如果是jsx文件,那么尖括号的书写方式可能会有语法冲突,因此推荐使用as的推断方式

Part 06 - TypeScript类Classes

classes类可以用来描述一类具体事物的抽象特征

类的定义

这里类的使用和js中的使用方法没有什么不同,包含同样的成员,即属性,构造函数和方法。

但值得注意的是在ts中你必须在声明时在属性或构造函数中设定初始值,而不是像es6中在构造函数动态添加

class student 
  name: string;
  age: num;
  constructor(name: string, age: num) 
    this.name = "张三";
    this.age = 18;
  
  study(course: string): void 
    console.log(`$this.name今年$this.age岁了。他今天准备上$course`);
  

类的继承

TypeScript中的类同样可以通过子类继承父类后子类的实例,拥有父类中的属性和方法。同样通过super去调用父类的实例和获取父类的this等等。并且仍然可以通过 extends 关键字来实现继承。这种增强代码的可复用性在TypeScript中被保留了下来。

class student 
 public name: string;
 public age: num;
  constructor(name: string, age: num) 
    this.name = "张三";
    this.age = 18;
  
  study(course: string): void 
    console.log(`$this.name今年$this.age岁了。他今天准备上$course`);
  


class four extends student 
  constructor(name: string, age: num) 
    super(name, age);
    this.name=name
    this.age=age
  
  study(grade: string): void 
    console.log(`$this.name今年$grade年级`);
    super.study("语文");
  


const Li = new four("李四", 22);
Li.study("三");

//李四今年三年级
//李四今年22岁了。他今天准备上语文课

类的修饰符

private 私有属性 只能在当前类的内部去访问

class student 
  private goodStudent: string = "三好学生";


class four extends student 
  constructor() 
    super();
    this.goodStudent // Error 属性“goodStudent”为私有属性,只能在类“student”中访问。
  


const Li = new four("李四", 22);

Li.study("三");
Li.goodStudent // Error 属性“goodStudent”为私有属性,只能在类“student”中访问。

但当我们把private修饰符交给constructor去使用,则既不能被继承也不能在外部进行实例化,只能够通过类内部的静态方法去实现。

class student 
  private constructor(name: string, age: num) 
  
  static go() 
    return new student();
  


class four extends student  // 无法扩展类“student”。类构造函数标记为私有。


const Li = new student(); // 无法扩展类“student”。类构造函数标记为私有。
const create = Li.go() //Success

protected # 受保护属性 只能在类的内部去访问(可以作用在继承子类中)

class student 
  protected goodStudent: string = "三好学生";


class four extends student 
  constructor() 
    super();
    this.goodStudent // Success
  


const Li = new four("李四", 22);

Li.study("三");
Li.goodStudent // Error 属性“goodStudent”为私有属性,只能在类“student”中访问。

protected作用在构造函数中类似private的使用,但是是可以被继承的

readonly 只读属性 只读属性必须在声明时或构造函数里被初始化

class Student 
  readonly name: string;
  readonly age: number = 18;
  constructor(studentName: string) 
    this.name = studentName;
  


class Four extends Student
  constructor(name:string)
    super(name)
    console.log(this.name);
  

let three = new Student("张三");
let four = new Four("李四");
three.name = "王五"; // 错误! 无法分配到 "name" ,因为它是只读属性。
four.name = "赵六"; // 错误! 无法分配到 "name" ,因为它是只读属性。

类的存取器

TypeScript支持通过getterssetters来截取对对象成员的访问。 它能帮助你控制对对象成员的访问。

例如以下的这个方法,我们在修改权限之前通过set方法去进行判断密码的正确与否,如果不能通过控制权限则fullname仍然能够通过get取到旧的姓名。

let passcode = "密码";

class Employee 
  private _fullName: string = "旧名字";

  get fullName(): string 
    return this._fullName;
  

  set fullName(newName: string) 
    if (passcode && passcode == "密码") 
      this._fullName = newName;
     else 
      console.log("权限更新失败");
    
  


let employee = new Employee();

employee.fullName = "新名字";
if (employee.fullName) 
  console.log(employee.fullName);


抽象类

和接口的使用方法类似,同样是对成员的抽象,但不同于接口的是抽象类可以包含成员的实现细节。 
通过abstract关键字来声明和于定义抽象类和在抽象类内部定义抽象方法。

但是抽像类并不能被创建为实例。只能通过派生的子类继承后使用,并且super方法也不能访问父类中的抽象方法。

abstract class Family 
  people(name: string, relation: string): void 
    console.log(`我$relation叫$name`);
  
  abstract eat(food: string): void;


class Father extends Family 
  eat(food: string): void 
    console.log(food);
  


const father = new Father();
const family = new Family(); // Error!无法创建抽象类的实例。
father.eat("苹果");

Part 07 - TypeScript接口

你可以把接口理解为一种规范,可以用来规范对象的结构和类型。

TypeScript里,接口的作用就是约定对象当中包含了哪些成员,而这些成员的类型是如何指定的,以此来制定规范。

接口Interface

我们通过interface关键字来约定对象成员的结构,也就是说你必须拥有接口所约束的所有成员,并且成员必须符合指定的类型。

interface rsvrConfig 
  resName: string;
  resCode: number;
  resType: Array<string>;


function createRsvr(rsvrData: rsvrConfig) 
  console.log(rsvrData.resName);
  console.log(rsvrData.resCode);
  console.log(rsvrData.resType);

const rsvrData = 
  resName: "怀柔水库",
  resCode: 2002011,
  resType: ["PP", "ZZ", "ZQ"],
;

createRsvr(rsvrData);

可选属性

可选属性相当于在定义interface的时候,有些属性是可有可无的并不影响使用的,那么我们就会在定义时加一个来表示。

interface rsvrConfig 
  resName?: string;
  resCode: number;


function createRsvr(rsvrData: rsvrConfig) 
  console.log(rsvrData.resCode);


const rsvrData = 
  resCode: 2002011,
;

createRsvr(rsvrData);

可选属性的好处之一是可以对可能存在

以上是关于TypeScript入门版~适合初学者快速学习。的主要内容,如果未能解决你的问题,请参考以下文章

Python学习基础篇第一篇——快速入门(适合初学者)

快速入门:用Python做SQLite数据库开发(适合初学)

5分钟快速入门,用Python做SQLite数据库开发,附代码适合初学

超适合初学者的SpringBoot入门学习笔记,收藏起来慢慢看!

烧脑又有趣!苹果官方的「编程游戏」登陆 Mac,让你快速入门 iOS 开发

Python资料学习《疯狂Python讲义》+《教孩子学编程Python语言版》+《Python编程导论第2版》