TypeScript
2021-05-14 本文已影响0人
丽__
一、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"]
六、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文件中的枚举不会移除掉,使用常量枚举则可以移除
十二、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字符串