TS 介绍
TS 是什么
ts 是领有类型查看零碎的 javascript 超集, 提供了对 es6 的反对, 能够编译成纯 javascript,运行在任何浏览器上。
TypeScript 编译工具能够运行在任何服务器和任何零碎上。TypeScript 是开源的。
为什么要用 TS
ts 总体给我的感觉就是, 它能束缚代码, 又有肯定的灵便度, 能够造就你的编程习惯, 输入更高质量, 维护性高, 可读性高的代码
- 编译代码时,进行严格的动态类型查看, 编译阶段而不是运行时发现很多谬误, 特地是一些很低级的谬误
- 帮忙咱们在写代码的时候提供更丰盛的语法提醒, 不便的查看定义对象上的属性和办法
比方: 你给函数传了一个对象, 你在函数实现的时候还得记住对象外面都有啥参数, 你定义的参数名字是啥
TS 装置
npm init -ynpm install typescript -g
数据类型
- js 中的数据类型:
字符串(String)、数字(Number)、布尔(Boolean)、空(Null)、未定义(Undefined)、Symbol。
对象(Object)、数组(Array)、函数(Function) - ts 蕴含 js 中所有的类型, 而且还新增了几种类型
void、any、never、元组、枚举、高级类型
类型注解:
(变量/函数):type
布尔类型(boolean)
let flag: boolean = true
数字类型(number)
let num: number = 8;
字符串类型(string)
let str: string = 'sxh';
- 数组类型(array)
let arr1:number[]=[1,2,3]let arr2:Array<number>=[1,2,3]
只读数组 数组创立后不能被批改
let ro: ReadonlyArray<number> = arr1;// arr1.push(3);// ro[1] = 4;// ro.push(6);// ro.length = 100;// arr1 = ro;// let arr3: number[] = ro
元组类型(tuple)
管制了数组成员的类型和数量let tuple:[string,number]=['sxh',10]//元祖越界问题:tuple.push(2)//能够增加的类型是所有数组成员的联结类型console.log(tuple[2])//不能这样拜访
枚举类型(enum)
一般枚举
若枚举类型未指定值或指定的值为number类型, 可对其进行双向取值// 双向取值enum Color {RED,BLUE,}console.log(Color[0], Color[1]);console.log(Color['RED'], Color['BLUE']);enum Color {RED=2,BLUE,}enum ActionType {ADD = 'ADD',EDIT = 'EDIT',DELETE = 'DELETE',}
常量枚举
const enum Status {'success','warning','fail',}let loginStatus = [Status.success, Status.warning, Status.fail];
keyof typeof Enum, 将枚举类型转换为联结类型
enum ActionType {ADD,EDIT,DELETE,}type ActionTypeConst = keyof typeof ActionType // 'ADD' | 'EDIT' | 'DELETE'
null、undefined
null, undefined 是其余类型的子类型, 能够赋值给其余类型的变量
strictNullChecks 为 true 的话不能赋值给其余类型let str: string;str = null;str = undefined;
- 任意类型(any)
任意类型 any 类型 类型转换艰难的时候, 数据类型结构复杂,没有类型申明的时候用
如果变量定义为 any 类型, 跟 js 差不多了, 不进行类型查看了 unkonwn 未知类型
let a: any let b: unkonwna.toFixed()b.toFixed()
void 无类型
罕用于没有具体返回值的函数const handler = (param: string):void => {}
never 类型
永远不存在的值
任何类型的字类型, 能够赋值给任何类型
然而任何类型都不可赋值给 never, 包含 anyfunction error(msg: string): never {throw new Error('我报错了'); // 间接异样完结了}function loop(): never {while (true) {}}function fn(x: number | string) {if (typeof x === 'number') { // 类型爱护 console.log(x);} else if (typeof x === 'string') { console.log(x);} else { console.log(x);}}
类型推论
如果没有指定类型, TS 会依据类型推论推断出一个类型.
如果变量定义的时候没有赋值, 默认是 any 类型
let x; // 能够赋值为任何类型的值let x1 = '生生世世'; // x1会推论成sring类型, 不能给x1赋值为其余类型了// x1 = 222;
如果 TS 能正确推断出其类型, 咱们可采纳类型推论而不用定义类型
function sum(x: number, y: number){ return x + y;}
联结类型
let name1: string | number;// console.log(name1.toFixed());// console.log(name1.toString());name1 = 3;name1 = 'sxh';
类型断言
类型断言用来通知编译器 “我晓得本人在干什么”, 有 尖括号 和 as 两种写法. 在 tsx 语法中, 只反对 as.
let name1: string = '111'let name2: string | number;// console.log(name2.toFixed())console.log((name2 as number).toFixed());// 双重断言console.log((name1 as any) as boolean);
字符串字面量类型
//字符串字面量const left: 'left' = 'left';const right: 'right' = 'right';type pos = 'left' | 'right';function loc(pos: pos) {}// loc('up')
// 类型字面量type Person = { name: string; age: number;};let p1: Person = { name: 'sxh', age: 18,};
字符串字面量 vs 联结类型
type T1 = '1' | '2' | '3';type T2 = string | number | boolean;let t1: T1 = '2';let t2: T2 = true;
函数
函数定义
定义函数有两种形式: 1. 函数定义 2.函数表达式
// 1.间接申明function person2(name: string): void {console.log(name);}person2('sxh');// 2.变量申明let sum: (x:number, y:number) => numbersum = (a,b)=>a+bsum(1,2)// 3.类型别名type Sum = (a: number, b: number) => void;let sum: Sum = function (a: number, b: number): number {return a + b;};let sum2: Sum = function (a: number, b: number): void {// 没有返回值// return a + b;};const myAdd = (x: number, y: number) => x + y; // 也能够间接这样定义, 类型会主动推导// 4.接口interface Sum{ (x:number, y: number):number}let sum: Sum = (a,b)=>a+bsum(1,2)
可选参数
必须放在最初一个参数地位
function sum3(a: number, b: number, c?: number) {}sum3(1, 2);// 设置默认值, 最初一个参数设置默认值就, 函数调用可传可不传, 相当于可选参数function sum4(a: number, b: number, c = 6) {return a + b + c;}sum4(1, 2);// 第一个参数设置默认值, 应用默认调用的时候必须传 undefiendfunction sum5(a = 3, b: number) {return a + b;}console.log(sum5(undefined, 2));
残余参数
function sum6(...args: number[]) {return args.reduce((val, item) => val + item, 0);}sum6(1, 2, 3, 5);
函数的重载
给同一个函数提供多个函数定义
let catOpt: any = {};function cat(param: string): void;function cat(param: number): void;function cat(param: any) {if (typeof param === 'string') {catOpt.name = param;} else if (typeof param === 'number') {catOpt.age = param;}}cat('小花');cat(3);function add(a: string, b: number): void;function add(a: number, b: number): void;function add(a: string | number, b: string | number): void {}add(1, 2);// add(1, '2');
类
如何定义类
class Book { name: string; getName(): void { console.log(this.name); }}let book1 = new Book();book1.name = 'ts';book1.getName();
存取器
通过存取器来扭转一个类中属性的读取和赋值行为
class MyBook { bname: string; // 属性 constructor(bname: string) { this.bname = bname; } get name() { return this.bname; } set name(value) { this.bname = value; }}let myBook = new MyBook('ts');myBook.name = 'js';console.log(myBook.name);
参数属性
class MyBook1 { // bname: string; constructor(public bname: string) { // this.bname = bname; } get name() { return this.bname; } set name(value) { this.bname = value; }}let myBook1 = new MyBook1('ts');myBook1.name = 'js';console.log(myBook1.name);
readonly
class MyBook2 { readonly bname: string; // 公开的只读属性只能在申明时或者构造函数中赋值 readonly num: number = 1; constructor(bname: string) { this.bname = name; } changeName(value) { // this.bname = value; }}
继承
class Animal { name: string; constructor(name: string) { this.name = name; } eat(food: string) { console.log('吃什么', food); }}class Cat extends Animal { color: string; constructor(name: string, color: string) { super(name); this.color = color; }}let cat = new Cat('哈哈', 'white');console.log(cat.name);cat.eat('fish');
类外面的修饰符
public 私有属性, private公有属性, protected受爱护的
// public 私有属性 , ts默认为publicclass Animal1 { public name: string; // 本人, 子类和实例都能够拜访 private age: number = 2; // 本人能够拜访, 子类 和 实例 都不能够拜访, protected body: string; // 本人和子类能够拜访, 实例不能够拜访 public constructor(name: string, age: number) { this.name = name; this.age = age; } public eat(food: string) { console.log('吃什么', food); } private getAge() { return this.age; }}class Dog extends Animal1 { color: string; constructor(name: string, age: number, color: string) { super(name, age); this.color = color; } dogInfo() { // console.log(this.name); // console.log(this.body); // console.log(this.age); }}let an = new Animal1('哈哈', 2);let dog = new Dog('哈哈', 2, 'white');console.log(dog.name);// console.log(dog.age);// console.log(dog.body);// console.log(dog.getAge());
动态属性 静态方法
类本身上的属性和办法
class Button { static type = 'link'; static getType() { return Button.type; } public content: string; constructor(content: string) { this.content = content; }}console.log(Button.getType);console.log(Button.type);class SubButton extends Button {}let btn = new SubButton('ok');SubButton.type = 'e';console.log(Button.type);console.log(SubButton.type);
抽象类
是抽象概念, 不能被实例化
abstract class Input { label: string; abstract changeValue(): void; // 此办法在子类中必须得实现}class SearchInput extends Input { changeValue() {} // 必须得实现抽象类里形象办法}
形象办法 不蕴含具体实现, 必须在子类中实现
有关键字 abstract