TypeScript学习笔记

111 阅读5分钟
  • tsc可以将ts文件为js格式
tsc demo.ts // 将指定的ts文件编译为js文件
tsc demo.ts -w  // 将指定的ts文件编译为js文件,并监视后续变化,动态编译
tsc // 将所有ts类型文件编译为js文件,需要配置tsconfig.json文件
tsc -w // 将所有ts类型文件编译为js文件,并监视后续变化,动态编译,需要配置tsconfig.json文件
  • tsconfig.json文件是ts编译器的配置文件
{
  "include": [
    "./src/**/*" // *代表任意文件,**代表任意目录
  ],
  "exclude": [
    "./src/heelo/**/*" // 具有默认值,常见忽略目录不用设置
  ],
  "files": [
    "demo.ts", // 指定文件进行编译,一般不使用这种方式
  ],
  "compilerOptions": {
    "target": "ES5", // 默认ES3
    "module": "ES2015",
    // "lib": [], // 一般不需要设置,除非是在非浏览器环境下,比如node环境
    "outDir": "./dist", // 指定编译后的js文件输出路径
    "outFile": "./dist/app.js", // 将编译后的js文件合并到一个文件中(要合并多个模块,module必须使用amd或system)
    "allowJs": false, // 是否将js文件纳入编译范围
    "checkJs": false, // 是否检查js文件
    "removeComments": false, // 是否移除注释
    "strict": false, // 所有严格检查的总开关,建议开启
    "noEmit": false, // 不输出编译后的js文件,只能用检查功能
    "noEmitOnError": false, // 当有错误时不生产编译后的文件
    "alwaysStrict": false, // 是否开启严格模式,检查校验规则更严格,执行性能更强,在js文件中可以使用"use strict"开启严格模式
    "noImplicitAny": false, // 不允许隐式any类型
    "noImplicitThis": false, // 不允许隐式类型的this
    "strictNullChecks": false, //严格检查空值
  }
}
  • 可以使用字面量赋值
let a: 10;
// |的作用的连接多个类型
let a: 10 | 20; // 可以赋值为10或者20
let b: number | string
  • ts常用的类型如下:
类型例子描述
number1、33、2.5任意数字
string'hi'、"hello"、hi任意字符串
booleantrue、false布尔值true或false
字面量其本身限制变量的值就是该字面量的值
any*任意类型
unknow*类型安全的any
void空值(undefined)没有值
never没有值不能是任何值
object{name: "张三"}任意的JS对象
array[1,12,43]任意JS数组
tuple[4,5]元素,TS新增类型,固定长度数组
enumenum{A,B}枚举,TS新增类型
  • 关于any类型
    • 未显示声明类型时,变量类型默认为any
    • 不推荐使用any(因为可能会影响赋值源数据的类型校验)
    • 可以使用unknown(unknown类型的变量不能赋值给其他类型变量)
    • 实际上unknown就是一个类型安全的any
    • 如果必须将一个非unknown的值赋值给unknown类型的变量,可以进行类型判断
let e: unknown;
let s: string;
e = "hello";
s = e; // 会报错
if (typeof e === "string") {
  s = e; // 不报错,能够正常赋值
}
​
// 也可以使用类型断言来进行赋值
s = e as string;
  • void一般用于没有返回值的函数
  • never一般用于抛出异常的函数(程序不在继续执行,永远不会返回任何值)
  • 一般不使用object,而是定义实际对象的属性类型
let a: object; // 一般不这样写
let b: {
  name: string,
  age: nunber
};
​
b = {name: "张三"}; // 报错,因为少了age
b = {name: 123};   // 报错,因为name类型错误
b = {name: "张三", age: 16, sex: "男"}; // 报错,因为多了sex// 可以在变量名后增加?,变成可选属性,可选属性可以省略
let c: {
  name: string,
  age?: nunber
};
​
// 或者定义任意类型的属性
let c: {
  name: string,
  [propName: sring]: any
};
  • 函数的定义也可以进行类型限制
let d: (a: number, b: number) => number;
  • 数组的定义,可以限制数组中存储数据的类型
let f: string[];
let g: Array<number>;
  • 元组其实是一个固定长度(2)的数组,可以指定类型
let x: [string, number];
  • 枚举的使用方法:
enmu Gender {
  Male,
  Female
}

gender = Gender.male; // 0
  • 连接类型符号除了|,还有&,作用是同时满足两个类型校验条件
let j: {name: string} & {age: number};

j = {name: '张三', age: 18}; // 必须同时满足定义时的类型条件
  • 可以通过type给类型起别名,简化类型定义的使用
type myType = string; // 意义不大
type myType = 1 | 2 | 3 | 4 | 5;
let k: myType;
  • class中的属性包括实例属性和类(静态)属性,方法也一样
class Person {
	name: string = "张三"; // 实例属性,通过实例访问
	static type: string = "人";  // 静态属性,通过类访问
   
	readonly desc: string = `${name} 是一个${type}`; // 只读属性
}
  • ts中的构造函数是constructor,其中包含this指针
constructor(name: string, age: number) {
  // 在构造方法中this代表当前实例 
  this.name = name;
  this.age = age * 2;
}
// 也可以将属性直接定义在构造方法参数列表中
constructor(public name: string, public age: number) {
}
  • ts支持继承、多态、重载、super、抽象类 、接口

  • ts中的接口除了用于类实现,还可以用于限定变量类型

interface MyType {
  name: String;
  age: number;
}

class A implements MyType {
  // 这种属性生命方式不安全
  name: String;
  age: number;
  constructor() {
      this.name = "";
      this.age = 18;
  }
}

let a: MyType;

// 而且接口支持重复定义,重复定义时代表使用两个interface的合集
  • ts种的类型修饰符有static、public(默认)、private、protected

  • 下面是更安全的属性定义方式

private _name: string;

// 读取属性的方法
getName() { // 使用方法p.getName() 
// 或者get name() { // 使用方法p.name
  return this._name;
}

// 设置属性的方法
setName(name: string) {
  // 配置规则,符合规则的name值才可以设置成功
  if (name !== this._name) {
		this._name = name; 
  }
}
  • ts的方法和类中都支持泛型,可以同时指定多个泛型 ,可以指定继承自类或者接口

  • 对于getElementById方法获取的属性,赋值给变量时,可能为空,这时可以进行空判断或者直接使用!进行强制使用(告诉编译器该变量一定不为空)

PS:如果有需要补充的内容,请在评论区留言

转载时请注明“来自掘金 - EvenZhu”