typescript(一)

1. typescript是什么?

1. typescript是微软开发的一款新的编程语言。

2. typescript是javascript的超集,它包含ES7/ES6/ES5,遵循最新的ES规范。它扩展了javascript语法。

   它弥补了javascript在类型检查方面的弱点。它在编译阶段提供了丰富的类型检查的语法提示。

2. 为什么要用typescript?

1. 越来越多的项目基于ts开发,如vue3, react16, VSCode

2. ts提供的编译阶段的类型检查,可以避免很多线上错误。

3. 安装

1. 全局安装

cnpm install -g typescript

生成一个全局命令: tsc

可以直接使用

tsc xxxx.ts

将ts文件转为同名的js文件。

但是每次都这么使用,会非常繁琐。可以在package.json中,配置脚本命令。

scripts: {
   "build": "tsc",
   "dev": "tsc --watch"
 }

类似webpack,脚本命令需要对应的配置文件。

扫描二维码关注公众号,回复: 8399973 查看本文章
tsc --init // 生成一个tsconfig.json的配置文件

4. 数据类型

1. 基本数据类型

let myname: string = 'lyra';
let age: number = 18;
let married: boolean = false;

2.数组

1)指定某一类型的数据

2)长度不定

let arr:Array<number> = [1,2,3];
let hobbies:string[] = ['football', 'reading'];

3. 元组类型

1)长度和类型都固定

2)每一项类型都可不同

let info:[string, number, boolean] = ['lyra', 18, false];

4. 普通枚举类型

enum Gender{ 
  BOY,
  GIRL
}
/**
 * 相当于Gender[0] = "BOY"; Gender["BOY"] = 0;
 *      Gender[1] = "GIRL"; Gender["GIRL"] = 1;
 */
let gender1:Gender = Gender.BOY; // 0
let gender2:Gender = Gender.GIRL; // 1

5. 常量枚举类型

1)因为是常量,不生成对象,编译阶段就被删除;
2) 只能通过属性访问。
const enum Color {
  RED=1,// 指定其实数值
  BLUE,
  YELLOW
}
// 被编译成console.log(1 /* RED */, 2 /* BLUE */, 3 /* YELLOW */)
console.log(Color.RED, Color.BLUE, Color.YELLOW); // 1 2 3

6. 联合类型

当数据可能有多种类型时

let temp1:number|string = '2';
let temp2:number|string = 2;
// 可能是空
let node:HTMLElement|null = document.getElementById('root');
// !非空断言操作符:指定其不可能为空
node!.style.color = 'red';

7. any类型

可以是任意类型; 等于不指定类型

1)当数据结构复杂 2)引入第三方库没有类型文件 3)可能发生类型转换
let temp:any = [1,23];
let temp2:any = 'str';

8. null和undefined

当tsconfig.json中的StrictNullChecks=false时,null/undefined为其他类型的子类型
let a:number; // StrictNullChecks:false
a = undefined;
a = null;

但是StrictNullChecks默认为true,此时需要

let a:number|null|undefined;

9. void类型

非任何类型;一般指不返回任何值。

function fn(name:string):void {// 指定返回值是void
  // 当StrictNullChecks=true时
  return undefined; //或者不返回, null会报错
  // 如果想使得return null也可以,则需要设置当StrictNullChecks=false
}

10.never类型

1)永远不会有返回值

2)或者永远访问不到

1. 比如一个一直执行的任务:如轮询任务

function loop():never { // 用于一直运行不停止的功能:如轮询等
  while(true) {
    // 死循环
  }
}

2. 抛出异常

function err():never {
  throw new Error('err');
}

3. 永远访问不到

function test(x:number|string) {
  if(typeof x === 'number') {
    console.log(x); // number
  } else if(typeof x === 'string') {
    console.log(x); // string
  } else {
    console.log(x); //此时x是never类型
  }
}

11. 类型推导

当不指定数据类型,但是初始化时赋值具体的值时,ts会默认其为初始值的类型。

let a1 = 10; // ts默认a1是number类型
a1 = 'str'; // 报错!

想要上面的不报错,可以:

let a2; // 此时默认a2:any
a2 = 10;
a2 = 'str';

或者

let a3: any = 10;
a3 = 'str';

12. 包装对象

js中有三种包装对象。Number,String,Boolean。
当其对应的原始类型的值调用属性或者方法时,js会将原始类型的值自动装箱,即打包成对象。
let x: string= 'somethings';
x.toLowerCase()
// 内部自动打包成
new String(x).toLowerCase()

13. 类型断言

手动指定不确定类型的数据为某种类型

// 强制告诉ts,指定数据的类型
let s:number|string|null|undefined; 
// 通常变量不能在赋值前使用;因为s有undefined类型,不会报错
(s as string).length; //使得遍历可以使用特定类型的方法

14. 字面量类型

将具体的值组合在一起,构成字面量类型。该类型从指定的数据中取值。

比枚举类型更自由。

let n:1|2|'d'|true|[1,2]; //n可以是1,2,'d',true,[1,2]中的任意一个值

5. 函数

1. 函数定义-函数声明

// 指定参数类型为string,返回值类型string
function fn(name: string):string {
  return 'hello' + name;
}
noImplicitAny属性
// 当不指定参数类型时,会暗示类型为any类型。此时会给出提示,希望可以指定具体的类型。
// 会出现该提示是因为tsconfig.json中默认noImplicitAny: true
// 如果修改noImplicitAny: false, 该提示会不再出现
function foo(name) {//Parameter 'name' implicitly has an 'any' type

}

2. 函数定义-函数表达式

// 定义一个类型,用来约束函数表达式
type barType = (x:string) => void; // x是形参
let bar:barType = function(name: string):void {

}

3. 可选参数

当有些参数可有可无时

// age参数可有可无
function print(name: string, age?: number):void {
}
print('lyra');
print('lyra', 18);

4. 参数默认值

function ajax(url: string, method:string='GET'):void {
  console.log(url, method); //'/user' 'GET
}
ajax('/user')

5. 剩余参数

当传参的数量不固定时,使用剩余参数

function sum(...numbers:Array<number>):void {
  console.log(numbers)
}
sum(1,2,4); //[1,2,4]
sum(1,2,3,4); // [1,2,3,4]

6. 重载

在Java中,重载指的是同名函数,但是定义的参数个数或者类型不同。
在TS中,指的是为同一个函数提供多个函数定义,限制函数实现的参数等。
const obj = {name: 'a', age: 10};
function attr(val: string):void; // 函数定义;后面只能跟函数定义或者函数实现
function attr(val: number):void; // 函数定义
function attr(val: any):void { //函数实现
  if(typeof val === 'string') {
    obj.name = val;
  } else if(typeof val === 'number') {
    obj.age = val;
  }
}
attr('lyra');
attr(20);
attr(true); //!报错! 根据上面,参数受限于函数定义的参数类型

6. 类

1. 属性和方法

class Person {
  // strictPropertyInitialization: true
  // 默认是true,即必须给属性赋初值
  // 初始化有两种方式:1)直接赋值 2)在constructor中赋值
  name:string = 'lyra'; //实例属性-直接赋值
  age: number;
  constructor(age:number) {
    this.age = age; //实例属性-构造函数中接受外部传入的参数赋值
  }
  getName() { // 原型链上的方法
    return this.name;
  }
}

2. getter/setter 原型链上的属性

class User {
  myname:string;
  constructor(name:string) {
    this.myname = name;
  }
  get name() { //name是原型链上的属性
    return this.myname;
  }
  set name(val:string) {
    this.myname = val;
  }
}
const user = new User('lyra');
console.log(user.name); // lyra
user.name = 'lyraLee';
console.log(user.name); // lyraLee
console.log(user.hasOwnProperty('name')); // fasle
// 获取实例的原型对象使用Object.getPrototypeOf()
// __proto__是内部的私有属性,拒绝使用
console.log(Object.getPrototypeOf(user).hasOwnProperty('name')); //true

3. 访问控制修饰符

 public: 公共属性;可以在类自身,子类,及外部访问;
 protected: 受保护属性;只能在类自身,子类访问;
 private: 私有属性;只能在类自身使用。其他地方都不能使用
class Mother {
  public name:string;
  protected age:number = 18;
  private money:number = 500;
  constructor(name: string) {
    this.name = name;
  }
  getName() {
    return this.name; // ✅自身可访问public属性
  }
  getAge() {
    return this.age; // ✅自身可访问protected属性
  }
  getMoney() {
    return this.money; // ✅自身可访问private属性
  }
}
class Child extends Mother{
  getName() {
    return this.name; // ✅子类可访问public属性
  }
  getAge() {
    return this.age; // ✅子类可访问protected属性
  }
  getMoney() {
    return this.money; //❌子类不能访问private属性
  }
}
const mother1 = new Mother('Lucy');
console.log(mother1.name); // Lucy ✅外部可访问public属性
console.log(mother1.age); // ❌ 外部不能访问protected属性
console.log(mother1.money); // ❌ 外部不能访问money属性

4. 只读属性readonly

class Animal{
  readonly age:number;
  constructor(age:number) {
    this.age = age; //只读属性,可以进行初始化
  }
}
const dog = new Animal(10);
console.log(dog.age); //10
dog.age = 20; //❌因为是只读属性

5. 静态属性static

class Book{
  // 相当于Book.author = 'lyra';
  static author = 'lyra';
  // 相当于Book.getAuthor() {}
  static getAuthor() { 
    // this取方法运行时所在的对象,此时this是类本身
    console.log(this.author); // lyra
  }
}
Book.getAuthor() // 'lyra'

6. 抽象类/方法 abstract

只能被继承,不能别实例化(不能使用new命令);

封装了一些公共属性和方法,供子类调用;还可以设置公共方法必须被重写

abstract class Parent{
  public name:string = 'parent';
  public giveMoney() {
    throw new Error('该方法必须被重写')
  }
}

猜你喜欢

转载自www.cnblogs.com/lyraLee/p/12142438.html