typescript 学习笔记

一些概念知识点

  1. javascript设计之初,存在缺陷
typeof NaN // 'number'
0.1+0.2 // 0.30000000000000004
true==1 //true
9+'1'  //'91'
[]==0 // true
  1. javascript的更新迭代


    时间轴
  2. javascript与typescript的区别与联系

  • ts是js的超集,typescript = type + javascript,额外增加了:类型系统;
  • ts包含js,针对js一些缺陷进行限制,比如: 某个变量一旦定义了类型,那么无法二次定期其类型;
  • ts在编码阶段就可以进行语法校验,发现报错,而非要运行起来才发现,提高编程效率;


    TS包含JS
  1. 为什么一定要学习ts
  • 除了可以提高编码效率,此外最重要的是,大型前端框架底层使用ts(vue3);
  • vue3、react 创建项目时候都支持使用typescript;
  • 大型项目都在推荐使用typescript;
  • ts拥有类型推断机制,不需要在代码每个地方都显示标注类型,降低书写成本;
  • ts已成为大中型前端项目的首先编程语言;

typescript安装与解析

  1. 安装ts与基本配置
  • 因为node端与浏览器端,均不识别.ts文件,因此需要安装编译工具进行转换,生成js后才可被浏览器解析


    编译过程
  1. 浏览器端解析ts文件
  • 安装
npm install -g typescript
  • 解析
tsc test.ts
  • 常用指令
//查看版本号
tsc -v
//初始化一个tsc配置文件(tsconfig.json)
tsc --init
  • tsconfig.json配置
{
    "compilerOptions":{
        //自动编译
        "watch": true,
        //删除编译后注释
        "removeComments": true,
        //编译目标版本
        "target": "es5"
    }
}
配置信息

配置信息-说明1

配置信息-说明2
  1. 类型声明文件的使用说明
    xxxx.d.ts 为 xxxx.js 的类型约束说明文件


    类型文件说明1

    类型文件说明2
  2. 服务端解析ts文件

  • 安装
npm i -g ts-node
  • 解析
ts-node test.ts

类型注解分类

  1. JS已有类型
    原始类型(基本类型): number,string,boolean,null,undefined,symbol
    对象类型(引用类型): object( 数组,函数,对象等)

  2. TS新增类型
    联合类型、自定义类型(类型别名)、接口、元祖、字面量类型、枚举、void、any等

类型注解 - (javascript已有类型)

  1. 原始类型(基础类型)
  • number数字类型
let num1: number = 6;
  • string字符串类型
let name: string = '张三';
  • boolean布尔值
let isTrue: boolean = true;
  1. 对象类型(引用类型)
  • object对象类型
//方法名(): 返回值类型  --  sayFn(): string
let person: { name: string, age: number, sayFn(): string } = {
    name: '张三',
    age: 20,
    sayFn(){
        return '你好~';
    }
}

通过接口可以简化对象的书写

interface Person {
  name: string
  age: number
  sayFn(): string
}
let person: Person = {
    name: '张三',
    age: 20,
    sayFn(){
        return '你好~';
    }
}
  • array数组
//单一类型
let arr1: number[] = [1,2,3,4];
let arr2: string[] = ['张三','李四'];
let arr3: boolean[] = [true,false];
//联合类型,可以通过管道(|)将变量设置多种类型
let arr4: (number | string)[] = [10,'hello'];
  • 函数类型注解
// 参数类型为数字类型,返回值为字符串
function someFn(name: number):string{
    return '返回的是'+ name;
}
// 参数类型为数字类型,返回值为数字类型
function addFn1(num1: number,num2: number): number{
    return num1+num2;
}
// 书写方式2
const addFn2 = (num1: number,num2: number): number => {
    return num1+num2;
}
// 参数可选值
function mySlice(start?: number, end?: number){
  console.log('开始索引',start,'结束索引',end);
}
  • 同class约束兼容相同,函数也可以相互兼容


    函数约束相互兼容1

    函数约束相互兼容2
  1. class类
  • 设置class中属性类型;
class Person {
  name: string
  age: number
  constructor(name: string,age: number){
    this.age = age;
    this.name = name;
  }
}
let P1 = new Person('张三',20);
console.log('类的使用: '+P1.name,P1.age);
  • 设置class中方法
class Countobj {
  x = 10
  y = 20
  //实例方法
  scaleFn(n: number): void{
     this.x*=n
     this.y*=n
  }
};

let P1 = new Countobj();
P1.scaleFn(2);
console.log(P1.x); //20
console.log(P1.y); //40
  • class的继承,通过extends关键词实现
class Animal {
  move(){
    console.log('走~');
  }
};
class Dog extends Animal {
  say(){
    console.log('汪~');
  }
};
const Dog1 = new Dog();
console.log(Dog1.move() , Dog1.say());
  • class的方法修饰符
    public (公有的--默认值,可省略) protected(受保护的) private(私有的)
//-- 公有的,类与实例都可以用
class Animal {
  public move(){
    console.log('走~');
  }
};

//-- 类与继承的类,里面都可使用,但是实例无法使用
class Animal {
  protected move(){
    console.log('走~');
  }
  say(){
    this.move(); //可以调用
    console.log('汪~');
  }
};
let Dog = new Animal();
Dog.move(); //报错,无法使用

//-- 只有自己的类能用,继承的子类,实例均无法使用
class Animal {
  private move(){
    console.log('走~');
  }
  say(){
    this.move(); //可以调用
    console.log('汪~');
  }
};

class Dog extends Animal {
  eat(){
    this.move(); //报错,无法使用
    console.log('吃~');
  }
};

let Dog = new Animal();
Dog.move(); //报错,无法使用
  • class的属性修饰符readonly
class Person {
  readonly age: number = 18
  constructor(age: number){
    this.age = age
  }
};
let Person1 = new Person(20); //报错:属性无法修改,因为类型为readonly
  • class类型约束,可以相互兼容 - (兼容规则: 约束参数少,可以被约束多的兼容)
class Point { x:number, y:number }
class Point3D { x:number, y:number, z:number }
const p: Point = new Point3D()

类型注解 - (typescript新增类型)

  1. 类型推断
  • 没有明确指出类型的地方;
  • 触发类型推论的2种场景:
    情况1.声明变量并初始化时候
    情况2.决定函数返回值时候;

注:
如果不知道类型,可以通过鼠标放在变量名称上,利用VSCode的提示来查看类型;

情况1: 声明变量并初始化值

let age: number
age = 18;
//等同于 声明变量类型,赋值为18
let age = 18;

情况2: 根据函数参数和内部处理,判断返回值

function addFn(num1: number, num2: number){
  return num1+num2;
}
// 等同于
function addFn(num1: number, num2: number): number
  1. void、any、可选值、默认值
  • 函数中没有返回值的情况下,设置其为void
function hiFn(name: string):void{
    //函数没有返回值
    console.log(name);
};
  • 定义一个变量,不赋值,不设置任何类型约束,设置其为any
let some: any;
some = 1;
some = '你好';
  • 可选值、默认值 - (可选值放参数最后)
function showMes( name: string, sex: string='female',age?: number ){
  console.log('属性:', name, sex, age);
}
showMes('张三','male',15);  //-- 属性: 张三 male 15
showMes('李四');  //-- 属性: 李四 female undefined
  1. 类型别名 - (通过关键词'type'简化书写)
type myArray = (string | number)[];
let arr1: myArray = [1,'hello']
  • 同class约束兼容相同,类型别名也可以相互兼容


    类型别名相互兼容
  1. 接口 - (通过关键词'interface'来描述对象类型,达到复用)
  • 注意:接口类型中属性类型后没有;(分号)
interface Person {
  name: string
  age: number
  say(): string
}
let person: Person = {
  name: '张三',
  age:20
  say(){
     return '你好~'
  }
}
  • 同class约束兼容相同,接口也可以相互兼容


    接口约束相互兼容
  1. 类型别名与接口的区别与联系
  • 相同点:都可以给对象指定类型;
  • 不同点:接口只能为对象指定类型; 类型别名不仅可以为对象指定类型,也可为任意类型指定别名;
interface Person {
  name: string
  age: number
  say(): string
};
type Person = {
  name: string
  age: number
  say(): string
};
  1. 通过关键词implements,实现类的类型注解
interface Say {
  say(): string
};
class Dog implements Say {
  name: string
  constructor(name: string){
    this.name = name;
  }
  say(){
    return '汪~';
  }
};
let Dog1 = new Dog('小黑');
console.log(Dog1.say()); //'汪~'
console.log(Dog1.name); //'小黑'
  1. 元祖
  • 数组存在一个问题,就是只能指定类型,但是无法指定个数,元素出来可以解决这个问题
let position: number[] = [51.51,96.56];
//通过元祖,来明确声明有几个变量
//明确只有两个元素,类型为number
let position: number[number,number] = [51.51,96.56];
  1. 枚举 -- (推荐使用字面量类型+联合类型,这比枚举要直观、简洁、高效)
  • 通过关键词'enum'来声明枚举列表;
  • 普通枚举 - 有值,从0开始自增长;


    普通枚举
enum myList { up, down }
function showFn(name: myList){
    console.log(name)
};
console.log(showFn.up); //0
console.log(showFn.down); //1
  • 字符串枚举 - 不会自增长


    枚举解析js后
enum myList { student1='zhangsan', student2='lisi' }
function showFn(name: myList){
    console.log(name)
};
showFn(myList.student1); //'zhangsan'
  • 通过索引找到值
enum Color {Red = 1, Green, Blue}
let colorName: string = Color[2];  // 'Green'
  1. 字面量类型 -- (推荐使用!)
  • 字面量类型与联合类型一起使用;
  • 表示一组明确的可选值列表,在已有的选项中选择一项(只能在其中选择);
    优势:
    相对于string类型,使用字面量类型更加精确、严谨;
function showFn(direction:'up' | 'down' | 'left' | 'right'){
  console.log(direction);
};
showFn('up'); //'up'
  1. 类型断言
  • 使用as关键词实现类型断言;
  • 关键词as后面明确一个具体的类型(HTMLAnthorElement是HTMLElement的子类型);
  • 通过类型断言,aLink的类型变的更加具体,这样可以访问a标签的特有属性和方法;
    技巧:
    方法1:在浏览器控制台,通过console.dir()可以打印DOM元素信息,在属性列表最后,可查看元素的类型;
    方法2:通过VSCode的类型推断,查看DOM的具体类型


    类型推断DOM类型
//-- 将鼠标划入e,即可查看DOM具体类型 (如A标签的类型HTMLAnchorElement)
<input onChange={ e => {} } />
const aLink = document.getElementById('link') as HTMLAnchorElement;
const aLink = <HTMLAnchorElement>document.getElementById('link');
  1. 交叉类型
  • 交叉类型关键词'&',功能类似接口继承extends,用于组合多个类型为一个类型;
interface Person { name: string }
interface Contact { phone: number }
type PersonDetail = Person & Contact
let person1: PersonDetail = {
  name: '张三',
  phone: 13717777777
};
  • 通过交叉类型符号'&',解析后的效果:
type PersonDetail = { 
  name: string
  phone: string
}
交叉类型
  • 交叉类型与继承的关系
    相同点:都可以合并对象类型
    不同点:发生属性冲突时候,extends进行报错,&进行合并


    交叉类型与继承的关系
  1. 泛型
  • 无法提前定义类型约束,而是调用时候定义
  • 下面代码中调用时候,可以根据泛型<xxxx>,从类型xxx约束参数和返回值
function showMes<Type>(value: Type): Type{
  return value;
};
//-- 调用
console.log( showMes<string>('你好') ); //你好
console.log( showMes<number>(100) ); //100
  • 泛型的继承,关键词(interface、extends)
    表示传入的类型必须具有length属性,否则会报错;
interface Length {
  length: number
};
function showMes<Type extends Length>(value:Type):Type{
  cosnole.log(value.length);
  return value;
};
showMes([1,2,3]); //参数数组,返回数组,拥有length属性
showMes('abcd'); //参数字符串,返回字符串,拥有length属性
showMes({ length:10, name:'张三’ }); //参数对象,返回对象,拥有length属性

泛型的类型变量可以有多个,并且类型变量之间可以约束


多个类型约束的泛型
  • 实际使用中,数组就是一个泛型


    数组是一种泛型
  • 通过关键词( 'Partial'、'Readonly'、'Pick' )来约束泛型


    将泛型中的值,变为可选类型

    将泛型中的值,变为只读类型

    将泛型中的值,收集部分生成全新约束
  1. 泛型 - 索引类型签名


    索引类型签名
  2. 类型映射

type Props = { a: number; b: string; c: boolean }
type Type3 = { [ key in keyof Props ]: number }
//-- 解析后
type Type3 = {
  a: number
  b: number
  c: numner
}

实战使用ts

  1. 根据.js文件书写.d.ts文件


    规则描述书写
  2. 通过关键词‘declare’来区分js中已有的变量声明,表示仅为进行变量约束,而非重新定义变量


    规则描述书写

    规则描述书写-为独立文件,导出规则

    规则描述书写-为独立文件,导入规则
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349

推荐阅读更多精彩内容