0
点赞
收藏
分享

微信扫一扫

#yyds干货盘点#TypeScript学习笔记

孟祥忠诗歌 2022-02-18 阅读 53

类型系统

强类型 与 弱类型(类型安全角度)

  • 强类型:在语言层面限制函数的实参类型必须与形参类型相同
  • 弱类型语言不会限制实参的类型
  • 强类型有更强的类型约束,不允许有任意的隐式类型转换
  • 弱类型中几乎没有什么约束,允许任意的数据隐式类型转换
  • 变量类型允许随时改变的特点不是强弱类型的差异

静态类型 与 动态类型(类型检查角度)

  • 静态类型:
  • 一个变量声明时它的类型就是明确的
  • 声明过后,它的类型就不允许再修改
  • 动态类型:
  • 运行阶段才能明确变量类型,而且变量类型可以随时发生变化
  • 变量是没有类型的,变量中存放的值是有类型的

#yyds干货盘点#TypeScript学习笔记_TS

JavaScript 类型系统特征

  • 弱类型且动态
  • 缺失类型系统可靠性
  • 原因:
  • 早前 JavaScript 应用简单
  • JavaScript 没有编译环节,设置成静态类型语言没有意义

弱类型产生的问题

  • 只有运行阶段才能发现是否有问题
  • 类型不确定造成的函数功能问题,结果和预想的不一样( + )
  • 存在许多的隐式转换
  • 对于小项目可以通过约定来约束,但是开发周期长等的项目会有很大的隐患

强类型的优势

  • 错误更早暴露
  • 代码更智能,编码更准确
  • 重构更牢靠
  • 减少不必要的类型判断

概述

  • TypeScript 是 JavaScript 的超集
  • TS 使用更加完善的类型系统和新特性完成开发工作,完成开发工作后会编译成能够在生产环境运行的 JavaScript 代码
  • 任何一种 JavaScript 运行环境都支持
  • 功能比 flow 更为强大,生态更加健全、更完善
  • 属于 渐进式

#yyds干货盘点#TypeScript学习笔记_TS_02

  • 缺点:
  • 语言本身多了很多概念
  • 项目初期,会增加一些成本

基础使用

  1. 安装:yarn init --yes、yarn add typescript --dev
  2. node_modules/bin/tsc:tsc 命令帮助我们编译 TS 代码(yarn tsc 文件)
  3. 配置:yarn tsc --init 初始化配置文件
  • target:设置编译后的 JavaScript ECMAScript 标准
  • module:输出的代码会采用什么样的方式去模块化
  • outDir:编译结果输出的文件夹 dist
  • rootDir:源代码所在的文件夹 src
  • sourceMap:开启源代码映射
  • strict:严格模式
  • lib:指定所引用的标准库
  • 只有直接编译整个项目才会运行配置文件
  1. 中文错误消息:yarn tsc --locale zh-CN

类型

原始类型

  • 非严格模式都可以为空
  • 标准库:内置对象所对应的声明
// 原始数据类型
// 严格模式不能为空 null
const a: string = "";
const b: number = 0;
const c: boolean = true;
const d: null = null;
const e: undefined = undefined;
// void 只能存放 null/undefined
const f: void = undefined;
// target 改为2015+ 或者改 lib 引用库
const g: symbol = Symbol()

Object 类型

  • 泛指所有的非原始类型,也就是数组、函数、对象等
  • 如果要具体的对象类型 用字面量的形式
  • 赋值的对象结构必须与定义的结构完全一致

数组类型

  • 可以使用数组泛型
  • 元素类型[]
// 数组泛型
const ary1:Array<number> = [1,2]
// 元素类型[]
const ary2:number[] = [1,2]

元组类型

  • 明确元素数量
  • 明确元素类型
  • 每个元素不必完全相同
  • 特殊的数组,可以使用下标访问

枚举类型

  • 可以给一组数值取别名
  • 只会存在一些固定的值,不会出现超出范围的可能性
  • 会入侵到运行时的代码,会生成键值对保存起来,让我们更好的根据值获取名称
  • 如果我们确定我们不会采用索引器的方式去访问名称,那么可以采用常量枚举
// 如果不指定值会依次累加  
// 数值枚举:若指定第一个值 会在第一个值的基础之上进行累加
// 字符串枚举:只能自己手动赋值
// 添加 const 关键字 变成常量枚举
const enum Status {
ok = 0,
eror = 1,
}

函数类型

  • 函数定义方式:函数声明和函数表达式
  • 函数声明:
  • 参数的注解跟在其后 返回值的注解跟在括号后
  • 参数后面添加 ? 变成可选参数
  • 参数后面添加默认值之后 也会变成可选参数
  • 可选参数必须在必选参数后面
  • 函数表达式
  • 可以采用箭头函数的形式
function fun1(a:number = 10,b?:number,...res:number[]):string {
return 'fun1'
}
// 函数表达式
const fun2: (a?: number, b?: number | undefined) => string = function(a:number = 10,b?:number):string{
return 'fun2'
}
const fun3 = function(a:number = 10,b?:number):string{
return 'fun3'
}

任意类型(弱类型)

  • 动态类型
  • 不安全,轻易不使用

隐式类型推断

  • 在没有进行类型约束直接赋值时,会根据赋值类型来推断该类型
  • 推断出来后就相当于添加了 :类型
  • 没有推断出来就会是 any

类型断言

  • 当我们明确知道类型但是 TypeScript 不一定知道,此时我们可以明确告诉 TypeScript 类型
  • 方式:​​<类型>(JSX 下不能使用)、as​
  • 类型断言并不是类型转换(运行时的概念),只是编译过程中的概念,编译过后就不会存在了
const nums = [100,200,300]
const res = nums.find( x => x>0)
let age1 = res as number
let age2 = <number>res // JSX下不能使用

作用域问题

  • 直接在文件中定义的变量是在全局作用域中的
  • 我们可以使用立即执行函数进行包裹或者采用模块导出(就会成为模块作用域中的局部成员)的方式
(function() {const a = 123})()
const a = 123
export {}

接口

  • 一种规范或者契约,抽象概念
  • 约定对象的结构、约定有哪些成员而且这些成员的类型又是什么样的
  • 使用整个接口就必须遵循接口全部的约定
  • 使用 ​​interface​​ 关键字
  • ​?​​ :可选成员
  • ​readonly ​​修饰成员:只读成员,可以跟在访问修饰符后面
  • ​[类型]:类型​​:动态成员
interface Student {
name: string;
readonly age: number;
position?:string;
}
function banji(student: Student) {
console.log(student);
}
// 动态成员 不定数量 不定名称
interface Eat {
[key:string] : string
}

  • 描述一类事物的抽象特征
  • 用来描述一类具体对象的抽象成员
  • ES6 之前 :函数 + 原型 模拟实现类
  • ES6+:专门的 class
  • TS 增强了 class 的相关语法
class Person {
// 必须声明和初始化
name:string //= 'zhangsan' 初始化一般在构造函数中进行
age:number
constructor(name:string,age:number) {
this.name = name
this.age = age
}
}

访问修饰符

  • private:私有属性,只能在类中访问
  • public:公有成员,默认
  • protected:也不能在外部访问,只允许在子类中访问,允许继承
  • 如果给了构造函数添加了 private ,那么该类就不能被实例化也不能被继承,就只能在内部添加 静态方法,在静态方法中创建这个类的实例

类与接口

  • 接口可以对类进行抽象
  • 类后跟 ​​implements​​关键去实现接口
  • 实现一个接口后就必须包含接口中的全部方法和成员
interface EatFood {
eat (food: string): void;
}
class Animal implements EatFood{
eat(food:string) {
console.log("我吃:",food);
}
}

抽象类

  • 包含子类当中必须要有的成员,不同于的接口的是可以包含一些具体的实现
  • 比较大的类建议使用抽象类(例如:动物)
  • 只能被继承不能使用 new 的方式创建
  • 类前面使用 ​​abstract​​关键字
// 抽象出类中的公共的一些方法和属性
interface EatFood {
eat (food: string): void;
}
// ----------抽象类--------
abstract class Animal implements EatFood{
eat(food:string) {
console.log("我吃:",food);
}
// 抽象方法 没有方法体
abstract run(speed:number):void
}
class Cat extends Animal{
// 继承了抽象类就必须实现其方法
run(speed: number): void {
console.log('跑的速度:',speed);
}
}
const cat = new Cat()
cat.run(100)

泛型

泛型:指在定义函数、接口、类的时候,不去指定具体的类型,等到在使用的时候再去指定具体的类型

  • 为了极大的复用代码
  • 在定义的时候不明确的类型都采用 ​​T​​ 来代表
  • 在调用的时候把类型传递过去
function creatArray<T>(length:number,value:T):T[] {
return Array<T>(length).fill(value)
}
console.log(creatArray<number>(3,100));

类型声明

  • 一个成员在定义的时候因为种种原因没有进行声明一个明确的类型
  • 我们就可以在使用的时候单独为它进行类型声明
  • 使用 ​​declare​​ 关键字进行声明
  • 由于现在的社区非常完善,我们也可以安装相应的类型声明模块就行了
举报

相关推荐

0 条评论