TypeScript

一、TypeScript 概述(JavaScript的超集、扩展集)

image.png
  • 任何一种JavaScript运行环境都支持
  • 功能更为强大,生态更为健全,更完善
  • Angular 、Vue3.0 使用TypeScript取代flow
  • 前端领域中的第二语言
  • 缺点:本身多了很多概念,项目初期,TypeScript会增加一些成本
  • 好处:属于【渐进式】

二、TypeScript 快速上手

  • 安装yarn
npm install -g yarn
  • 查看yarn版本
yarn -v
  • 初始化package.json文件,用来管理依赖项
npm init -y
  • 安装 typescript
yarn add typescript --dev
  • 运行会生成对应的js
    会自动去除:number类型限制和编译成对应的js
yarn tsc .\01-getting-started.ts

三、TypeScript 配置文件

  • 使用命令yarn tsc --init自动生成tsconfig.json的配置文件文件
yarn tsc --init

配置部分tsconfig.json文件


image.png
  • 终端运行 tsc,会将src下的文件编译输出到dist目录下

四、TypeScript 原始类型

/**
 * 在非严格模式(strictNullChecks)下
 * string,number,boolean都可以为空
 * const d:string =null
 * const d:number = null
 * const d:boolean = null
 *  */ 
const d: null = null;
const e: void = undefined;
const f: undefined = undefined;

/**
 * Symbol是ES2015标准中定义的成员
 * 使用它的前提必须确保有对应的ES2015库的引用
 * 也就是 tsconfig.json中的lib选项必须包含ES2015
 */
const h: symbol = Symbol();

五、TypeScript 标准库声明

  • 标准库就是内置对象所对应的声明
    当tsconfig.json中target为“es5”时,const h: symbol = Symbol();会报错,因为es5标准中没有Symbol,解决方法,在tsconfig.json中的lib添加["ES2015"],同理console.log在浏览器当中是BOM所提供的,而在TypeScript中把BOM 和DOM都归结到DOM一个标准库中,所以lib中需要追加["DOM"]
image.png

六、TypeScript 中文错误消息

  • 可以使用中文的错误消息
yarn tsc --locale zh-CN

七、TypeScript 作用域问题

//不同文件定义相同类型的对象 会报错

// 作用域问题
(function () {
  const a = 123;
});

//或者
const a = 123;
export {};//作为模块导出,确保跟其他示例没有冲突

八、TypeScript Object类型

TypeScript中的Object类型并不单指普通的对象类型,而是泛指非原始类型,也就是对象,数组和函数

export {}; //作为模块导出,确保跟其他示例没有冲突

const foo: object = function () {}; //  []   {}

const obj: { foo: number; bar?: string } = { foo: 1 };

九、TypeScript 数组类型

const arr1: Array<number> = [1, 2, 3];

const arr2: number[] = [1, 2, 3];

function sum(...args: number[]) {
  return args.reduce((prev, current) => prev + current, 0);
}

十、TypeScript 元组类型

export {};
const tuple: [number, string] = [12, "张三"];

const [age, name] = tuple;

Object.entries({
  foo: 123,
  bar: 22,
});

十一、TypeScript 枚举类型

// 枚举类型
export {};
// 旧
const postStatus = {
  draft: 0,
  unPublished: 1,
  pbulished: 2,
};

// 常量枚举
const enum PostStatus2 {
  draft = 0,
  unPublished = 1,
  pbulished = 2,
}

const enum PostStatus3 {
  draft = 4, //默认从0开始,给了默认数值之后从当前数值开始增加
  unPublished,
  pbulished,
}

enum PostStatus4 {
  draft = 'fds',//可以是字符串  每个都需要填写
  unPublished = 1,
  pbulished = 2,
}

const post = {
  title: "hello TypeScript",
  content: "Typescript is a typed superset of JavaScript",
  status: postStatus.draft,
};

编译过后js文件中的枚举不会移除掉,使用常量枚举则可以移除

image.png

十二、TypeScript 函数类型

// 函数类型

export {}; //确保和其他示例成员没有冲突

// 不确定参数放在最后  使用? 表示
function fun1(a: number, b: number, c?: number) {
  return "func1";
}
fun1(1, 2);

// 可以传递更多不确定参数请在最后使用...reset
function fun2(a: number, b: number, ...rest: number[]) {
  return "func1";
}
fun2(1, 2, 3, 4, 5, 6, 7);

// 函数表达式对应的限制
// 参数和返回值的限制
const fun3: (a: number, b: number) => string = function (
  a: number,
  b: number
): string {
  return "fun3";
}; 

十三、TypeScript 任意类型

export {}; //确保和其他示例成员没有冲突

function stringify(value: any) {
  return JSON.stringify(value);
}

stringify(1);
stringify("fdsf");
stringify(true);

// any是不安全的

十四、TypeScript 隐式类型推断

export {}; //确保和其他示例没有成员冲突

let age = 18; //相当于添加了number的类型注解

// age = 'jk';//不能再将string类型赋值给number类型对象

let foo;//相当于添加了类型为any的类型注解

foo = 100;//可以重新赋值任意类型
foo = "string";

建议为每个变量添加明确的类型注解

十五、TypeScript 类型断言

export {}; //确保跟其他示例没有成员冲突

const nums = [110, 120, 130, 140];

const res = nums.find((i) => i > 0);
console.log(res); //typescript推断类型为number或undefined

// 方式一
const num1 = res as number; //断言为number类型
// 方式二
const num2 = <number>res; //断言为number,JSX下不能使用

十六、TypeScript 接口

export {}; //确保和其他示例中没有成员冲突

// 定义接口
interface Post {
  title: string;
  content: string;
}

function printPost(data: Post) {
  console.log(data.title);
  console.log(data.content);
}

printPost({
  title: "hello",
  content: "Typescript",
});

接口就是用来约束对象的结构,一个对象去实现一个接口,必须要拥有这个接口中所有的成员

十七、TypeScript 接口补充

// 定义接口
interface Post {
  title: string;
  content: string;
  subtitle?: string; //可选成员   添加  ?
  readonly summary: string; //只读 不可更改
}

const hello: Post = {
  title: "hello",
  content: "fds",
  summary: "只读,不能修改",
};

// hello.summary = 'other';//不能修改

interface cache {
  [key: string]: string;
}

const cache1: cache = {};

// cache1.1 ='value';//只能为string
cache1.foo ='value'
cache1.boo ='valued'

十八、TypeScript 类的基本使用

/**
 * 类:描述一类具体事务的抽象特征
 * ES6以前,函数 + 原型 模拟实现类
 * ES6开始,JavaScript中有了专门的class
 * TypeScript 增强了class 的相关语法
 */

export {};

class Person {
  name: string; //  = '初始值'
  age: number;
  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }
  sayHi(msg: string): string {
    console.log(`I am ${this.name}`);
    return "返回类型为string";
  }
}

十九、TypeScript 类的访问修饰符

  • public 公有
  • private 私有
  • protected 只能在子类成员中访问
class Person {
  public name: string; //  = '初始值' public 公有属性
  private age: number; //私有属性
  protected gender: boolean; //只能在子类成员中访问
  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
    this.gender = true;
  }
  sayHi(msg: string): string {
    console.log(`I am ${this.name}`);
    return "返回类型为string";
  }
}

const tom = new Person("tom", 19);
console.log(tom.name);
// console.log(tom.age);//age已经设置为私有成员,不能访问
// console.log(tom.gender); //也不能访问

// 创建子类继承Person
class Student extends Person {
  // 构造器添加private 外部不能访问,可以在内部添加静态方法创建实例
  private constructor(name: string, age: number) {
    super(name, age);
    console.log(this.gender); //可以访问
  }
  //   创建静态类外部可访问并且使用其中返回的创建实例方法
  static created(name: string, age: number) {
    return new Student(name, age);
  }
}

const jack = Student.created("jack", 20); //可以使用静态方法
console.log(jack.name);

二十、TypeScript 类的只读属性

  • readonly
    当readonly 和访问修饰符同时存在,readonly 写在访问修饰符的后面
protected readonly  gender: boolean; //只能在子类成员中访问 并且只读不能修改

二十一、TypeScript 类与接口

  • 使用 implements 关键字
// 类与接口

interface eat {
  eat(food: string): void;
}
interface run {
  run(distance: number): void;
}

class Person implements eat, run {
  eat(food: string): void {
    console.log(`优雅的进餐:${food}`);
  }
  run(distance: number): void {
    console.log(`直立行走:${distance}`);
  }
}
class Animal implements eat, run {
  eat(food: string): void {
    console.log(`大口大口:${food}`);
  }
  run(distance: number): void {
    console.log(`爬行${distance}`);
  }
}

二十二、TypeScript 抽象类

  • abstract
  • 在class前面添加abstract,为抽象类,当前类只能继承不能创建(new Animal)
  • /当父类中有抽象方法,继承的子类要去实现
export {}; //确保跟其他示例没有成员冲突

// 在class前面添加abstract,为抽象类,当前类只能继承不能创建(new Animal)
abstract class Animal {
  eat(food: string): void {
    console.log(`大口大口:${food}`);
  }
  //抽象方法不需要方法体  也就是{ }
  //当父类中有抽象方法,继承的子类要去实现
  abstract run(distance: number): void;
}

class Dog extends Animal {
  //当父类中有抽象方法,继承的子类要去实现
  run(distance: number): void {
    console.log(`奔跑速度为:${distance}`);
  }
}

const d = new Dog();
d.eat("小白");
d.run(100);

二十三、TypeScript 泛型

  • < T >
export {}; //确保和其他示例没有成员冲突


// 不适用泛型
function createNumbnerArray(length: number, value: number): number[] {
  const arr = Array<number>(length).fill(value);
  return arr;
}

function createStringArray(length: number, value: string): string[] {
  const arr = Array<string>(length).fill(value);
  return arr;
}

const res1 = createNumbnerArray(3, 100);
const res2 = createStringArray(3, "100");


// ·--------------------------------------------------------

// 使用泛型
function createArray<T>(length: number, value: T): T[] {
  const arr = Array<T>(length).fill(value);
  return arr;
}

const res3 = createArray<string>(3, "foo");

console.log(res1);
console.log(res2);
console.log(res3);

二十四、TypeScript 类型声明

// 类型声明

import { camelCase } from "lodash";
import qs from "query-string";


// declare function camelCase(input: string): string;
const res = camelCase("hello typed");


qs.parse('?key=fdfds&key2=fdfdfnmgf')

// yarn add @types/lodash --dev   类型声明模块
// yarn add query-string  //用来解析URL中的queryString字符串

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

推荐阅读更多精彩内容