做金属小飞机的网站,做自己的彩票网站,自己的网站在哪做的忘了,网站开发的基本流程图简介 TypeScript 是 JavaScript 的超集#xff0c;是 JavaScript#xff08;弱类型语言#xff09; 的强类型版本。
拥有类型机制文件后缀 .tsTypescript type ES6TypeScript 和 JavaScript 的关系类似 less 和 css 的关系TypeScript对 JavaScript 添加了一些扩展#x… 简介 TypeScript 是 JavaScript 的超集是 JavaScript弱类型语言 的强类型版本。
拥有类型机制文件后缀 .tsTypescript type ES6TypeScript 和 JavaScript 的关系类似 less 和 css 的关系TypeScript对 JavaScript 添加了一些扩展如 class / interface / module 等大大提升代码的可阅读性。不能在浏览器直接执行而是编译成 JavaScript 去掉类型和特有语法后才会运行:
与 JavaScript 相比的优势
静态类型检查可以在代码开发阶段就预知一些低级错误的发生。
类型声明文件
以为.d.ts 为后缀的文件内容为 TS 语法编写的各种类型声明定义数据函数、接口或类的类型 通常安装第三方库后若缺少类型声明文件会有报错提示安装必要的类型声明文件 若没有提示则可以在 https://www.npmjs.com/ 中搜索相应的类型声明文件 搜索关键字为 type/第三方库的名称 有的库没有类型声明文件可以自己写点我了解详细语法 也可以用命令行生成类型文件点我了解详情
学习资料
英文官网
https://www.typescriptlang.org/
中文文档 https://www.tslang.cn/docs/home.html
https://typescript.bootcss.com/
在线开发环境
https://www.typescriptlang.org/play/index.html 搭建本地开发环境 新建文件夹 TSdemo 初始化项目
npm init -y安装必要的依赖
npm i -D typescript nodemon ts-nodetypescript 用于将 TS 编译成 JSnodemon 用于 node 进程的重启ts-node 用于直接执行 TS 类型的文件
项目目录下创建文件 index.ts
let myNname: string 朝阳;console.log(myNname);修改 package.json 中的 scripts 为 scripts: {start: nodemon --exec ts-node index.ts},初始化 ts 的配置
npx tsc --init执行成功后会生成文件 tsconfig.json
启动项目 声明类型 值类型
// 字符串
let myNname: string 朝阳;// 数字
let num: number 10;// 布尔类型
let ifLogin: boolean true;
// 布尔类型支持赋值计算之后结果是布尔值的表达式
let bool: boolean !!0// null
let n: null null;// undefined
let u: undefined undefined;// symbol
let s: symbol Symbol();数组 []
// 空数组
let arr: [] [];// 元素只能是数字的数组其他类型的写法类似
let arr1: number[] [1, 2];// 元素只能是数字或字符串的数组| 表示或的关系
let arr2: (number | string)[] [1, 朝阳];// 即是number类型也可能是string数组
const numbers1: number[] | string[] [123, 333] // 正确
const numbers2: number[] | string[] [123, 333] // 错误// 对象数组
let todoList: {id: number;label: string;done: boolean;
}[] [{id: 1,label: 吃饭,done: false,},{id: 2,label: 编程,done: false,},
];// 使用类型别名(type alias)
type User { name: string; age: number }// 存储对象类型的内容
const objectArr: User[] [{name: zws,age: 18}
]// 构造函数声明类型
let arr_1: Arraynumber [1, 2];
let arr_2: Arraynumber | string [1, 朝阳];对象 {}
// 空对象
let o: {} {};
let o2: object {};// 必选属性的对象赋值时声明的属性必须有
let user: {name: string;age: number;
} {name: 朝阳,age: 35,
};// 可选属性的对象可选属性需写在必选属性的后面
let user2: {name: string;age?: number;
} {name: 晚霞,
};Object 、 {} 、 object 的区别 与Object类型相同的{}是最不具体的可以将对象、数组和基元分配给它 object是更具体的类似于{ [key: string]: any }可以给它分配对象和数组但不能分配原始类型的数据 { [key: string]: string }是最具体的它不允许任何原始类型、数组或具有非字符串值的对象被分配到它。
var o: object;
o { prop: 0 }; // OK
o []; // OK
o 42; // Error
o string; // Error
o false; // Error
o null; // Error
o undefined; // Errorvar p: {}; // or Object
p { prop: 0 }; // OK
p []; // OK
p 42; // OK
p string; // OK
p false; // OK
p null; // Error
p undefined; // Errorvar q: { [key: string]: any };
q { prop: 0 }; // OK
q []; // OK
q 42; // Error
q string; // Error
q false; // Error
q null; // Error
q undefined; // Errorvar r: { [key: string]: string };
r { prop: string }; // OK
r { prop: 0 }; // Error
r []; // Error
r 42; // Error
r string; // Error
r false; // Error
r null; // Error
r undefined; // Error类 class
class Person {}
const me: Person new Person()class Teacher {name: stringage: number
}const objectArr: Teacher[] [new Teacher(),{name: zws,age: 18}
]新增类型 以下类型为 TS 新增的在 js 中不存在的数据类型
任意类型 any
当不确定变量的类型时比如来自用户输入或第三方代码库的动态内容可以使用但尽量少用。
任何类型的值都可以赋值给 any 类型的变量
let a: any 你好
a 0// 多数据类型的数组
let list: any[] [1, true, free];未知的类型 unknown
TypeScript3.0版本新增的类型
任何类型的值都可以赋值给 unknown 类型的变量any 与 unknown 的区别 : unknown 需要明确类型后执行操作any 则不需要
let a: unknown 1;let b a 1; // 会报错 “a”的类型为“未知”可通过 as 声明类型解决
let a: unknown 1;let b (a as number) 1;永不存在的值 never
用于总会抛出异常或根本不会有返回值的函数表达式的返回值类型。 当变量被永不为真的类型保护所约束时该变量也是 never 类型。
用途
限制类型控制流程类型运算
// 返回never的函数必须存在无法达到的终点
function error(message: string): never {throw new Error(message);
}// 推断的返回值类型为never
function fail() {return error(Something failed);
}// 返回never的函数必须存在无法达到的终点
function infiniteLoop(): never {while (true) {}
}无类型 Void
即什么类型都不是通常用于描述函数没有返回值
function test(): void {
}void类型的变量只能被赋予undefined或null
let test: void undefined;元组 Tuple
即固定长度和类型的数组
let x: [string, number];
x [hello, 10];枚举 enum
一种全新的数据描述方式用于描述一组数量有限的系列数据。
数值枚举默认
// 枚举三原色
enum Color {Red, Green, Blue}
// 按枚举内容的字符串取值得到的是对应的下标类似数组的下标从0开始
let c: Color Color.Green; // c的值为1 // 枚举方向上下左右
enum Direction {Up,Down,Left,Right
}// 按下标取值可得到枚举内容的字符串
console.log(Direction[0]) // Up可以自定义下标的起点
// 将默认的下标 0 改为 下标 1则后续下标会依次递增
enum Direction {Up 1,Down, // 2Left, // 3Right // 4
}也可以自定义任意下标未定义的在上一个的基础上递增
enum Direction {Up 11,Down, // 12Left 6, Right, // 7
}甚至下标可以相同
enum Direction {Up 11,Down, // 12Left 11,Right, // 12
}console.log(Direction.Down); // 打印 12console.log(Direction); // 打印 { 11: Left, 12: Right, Up: 11, Down: 12, Left: 11, Right: 12 }如果下标使用了计算值或常量那么该字段后面紧接着的字段必须设置初始值不能默认递增值了
const getValue () {return 0;
};
enum ErrorIndex {a getValue(),b, // error 枚举成员必须具有初始化的值c
}
enum RightIndex {a getValue(),b 1,c
}
const Start 1;
enum Index {a Start,b, // error 枚举成员必须具有初始化的值c
}字符串枚举
枚举成员为字符串时其之后的成员也必须是字符串。
enum Direction {Up, // 未赋值默认为0Down 南,Left 西,Right 东
}类型断言 as 当你知道更确切的类型时可以使用类型断言类似类型转换但不进行特殊的数据检查和解构。
它没有运行时的影响只是在编译阶段起作用。 TypeScript会假设程序员已经进行了必须的检查。
let someValue: any this is a string;方式一as 【推荐】
let strLength: number (someValue as string).length;JSX中只可用 as 语法断言
方式二
let strLength: number (stringsomeValue).length;函数 声明函数类型 如果省略参数的类型TypeScript 会默认这个参数是 any 类型 如果省略返回值的类型如果函数无返回值那么 TypeScript 会默认函数返回值是 void 类型 如果函数有返回值那么 TypeScript 会根据我们定义的逻辑推断出返回类型。 函数体内使用的外部变量的类型不会体现在函数类型定义中。
// 命名函数
function add(arg1: number, arg2: number): number {return x y;
}// 箭头函数
const add (arg1: number, arg2: number): number {return x y;
};// 定义变量 add 并声明为函数类型
let add: (x: number, y: number) number;add (arg1: number, arg2: number): number arg1 arg2;使用 Interface 声明函数类型
interface Add {(x: number, y: number): number;
}使用 type 声明函数类型
type Add (x: number, y: number) number;可选参数
可选参数需放置在必选参数之后用 ? 标注
let add: Add (arg1: number, arg2?: number): string arg1 arg2;默认参数 号标注参数的默认值所有必须参数后面的带默认初始化的参数都是可选的
function add(x: number, y: number 20): number {return x y
}剩余参数
const handleData (arg1: number, ...args: number[]) {//
};函数重载
强类型语言中的函数重载定义几个函数名相同但参数个数或类型不同的函数在调用时传入不同的参数编译器会自动调用适合的函数。
TS 中的函数重载通过为一个函数指定多个函数类型定义从而对函数调用的返回值进行检查。
只能用 function 来定义不能使用接口、类型别名等。
// 这个是重载的一部分指定当参数类型为string时返回值为string类型的元素构成的数组
function handleData(x: string): string[];
// 这个也是重载的一部分指定当参数类型为number时返回值类型为string
function handleData(x: number): string; // 这个就是重载的内容了这是实体函数不算做重载的部分
function handleData(x: any): any { if (typeof x string) {return x.split();} else {return x.toString().split().join(_);}
}handleData(abc).join(_);
handleData(123).join(_); // error 类型string上不存在属性join
handleData(false); // error 类型boolean的参数不能赋给类型number的参数。接口 interface 用于自定义任意类型
interface Point {x: number;y: number;
}interface Point {x: number,y: number
}每个属性间的间隔可以说 ; 也可以是,
interface Person {name: string,age: number
}// 使用范例
let user: Person {name: 朝阳,age: 30
}可选属性 ?
interface Point {x: number;y?: number;
}可选属性的位置没有限制无需像函数的可选参数一样必须放在必传参数的后面。
只读属性 readonly
interface Point {readonly x: number;readonly y: number;
}赋值后 x和y再也不能被改变
let p1: Point { x: 10, y: 20 };
p1.x 5; // error!属性的合并
interface Person {name: string;
}interface Person {age: number;
}let user: Person {name: 朝阳,age: 35,
};但已经指定过类型的属性不能改为新类型
interface Person {name: string;
}interface Person {name: number; // 报错 后续属性声明必须属于同一类型
}若想定义为联合类型也需在最初的地方定义
interface Person {name: string | number;
}定义函数类型
interface SumFunc {(a: number, b: number): number;
}let c: SumFunc (a, b) a b;let d c(1, 2);定义索引类型
当定义了索引类型之后数组的length方法将不存在包括Array原型链上的其他方法也不存
interface Dic {[id: number]: string;
}const dic1: Dic {0: 你,1: 好,
};const dic2: Dic [你, 好];定义类类型含接口的实现 implements
用于给类添加约束比如限定类必须含有某类型的属性/方法等。
// 定义接口 ClockInterface有一个属性 currentTime值类型为 Date
interface ClockInterface {currentTime: Date;
}// 定义类 Clock 实现接口 ClockInterface
class Clock implements ClockInterface {// 因接口 ClockInterface 中有一个Date 类型的属性 currentTime,所以 类 Clock 也必须有这个属性currentTime: Date;constructor(arg: Date) {// 在构造方法中需给接口 ClockInterface 限定的属性 currentTime 赋值this.currentTime arg;}
}可简写为
class Clock implements ClockInterface {constructor(public currentTime: Date) {}
}绕开多余属性的类型检查 方式一索引签名 【推荐】
interface myType {name: string;// 添加索引签名来兼容多余属性[prop: string]: any;
}方式二类型断言 【不推荐】
强行声明其为目标类型
let myInfo: myType {name: 朝阳,age: 30,
} as myType;方式三类型兼容 【不推荐】
interface myType {name: string;
}// 使用解构赋值避开多余属性
let getName ({ name }: myType) {return name;
};let myInfo {name: 朝阳,age: 30,
};console.log(getName(myInfo));接口的继承 extends
与类的继承类似
// 基础类型 Person
interface Person {name: string;
}// Student 类型在 Person类型的基础上新增了学号 sid
interface Student extends Person {sid: number;
}// Teacher 类型在 Person类型的基础上新增了学科 class
interface Teacher extends Person {class: string;
}let student1: Student {name: 朝阳,sid: 1,
};let teacher1: Teacher {name: 朝阳,class: 前端开发,
};同时继承多个接口
extends 后写多个接口即可用 , 间隔
interface Shape {color: string;
}interface PenStroke {penWidth: number;
}interface Square extends Shape, PenStroke {sideLength: number;
}接口继承类
接口继承了类之后会继承成员(类型)但是不包括实现;接口还会继承 private 和 protected 修饰的成员但是这个接口只可被这个类或它的子类实现
// 定义类 Person
class Person {name: string;constructor(arg: string) {this.name arg;}
}// 接口 I 继承类 Person
interface I extends Person {}// 接口 I 只能被 类 Person 或 类 Person 的子类实现 implements
class Student extends Person implements I {}泛型 在定义函数、接口或类的时候不预先指定数据类型而在使用时再指定类型的特性。
泛型的作用
泛型可以提升应用的可重用性如使用其创建组件则可以使组件可以支持多种数据类型。
使用泛型
let printNum (arg: number) {console.log(arg);
};printNum(123);
printNum(123); // 会报错因参数只能是数字let printString (arg: string) {console.log(arg);
};printString(123); // 会报错因参数只能是字符串
printString(123);怎样才能写一个通用的打印方法呢 使用泛型
let printAnyType T(arg: T) {console.log(arg);
};printAnyType(123);
printAnyType(123);可见泛型即将类型设定为一个变量当代码执行时传入的类型是啥它就是啥从而大大拓展了代码的通用性。
泛型的语法
用 包裹类型的变量通常用大写字母 T 表示也可以是任意其他大写字母
多个泛型
// 定义函数 - 让元组中的两个元素互换位置
let exchange T, U(tuple: [T, U]): [U, T] {return [tuple[1], tuple[0]];
};let tuple1: [number, string] [1, 朝阳];let tuple2 exchange(tuple1);console.log(tuple2);