关于ts:TypeScript教程基础

TS 介绍

TS 是什么

ts 是领有类型查看零碎的 javascript 超集, 提供了对 es6 的反对, 能够编译成纯 javascript,运行在任何浏览器上。
TypeScript 编译工具能够运行在任何服务器和任何零碎上。TypeScript 是开源的。

为什么要用 TS

ts 总体给我的感觉就是, 它能束缚代码, 又有肯定的灵便度, 能够造就你的编程习惯, 输入更高质量, 维护性高, 可读性高的代码

  • 编译代码时,进行严格的动态类型查看, 编译阶段而不是运行时发现很多谬误, 特地是一些很低级的谬误
  • 帮忙咱们在写代码的时候提供更丰盛的语法提醒, 不便的查看定义对象上的属性和办法
    比方: 你给函数传了一个对象, 你在函数实现的时候还得记住对象外面都有啥参数, 你定义的参数名字是啥

TS 装置

npm init -y
npm 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: unkonwn
    a.toFixed()
    b.toFixed()
  • void 无类型
    罕用于没有具体返回值的函数

    const handler = (param: string):void => {}
  • never 类型
    永远不存在的值
    任何类型的字类型, 能够赋值给任何类型
    然而任何类型都不可赋值给 never, 包含 any

    function 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) => number
sum = (a,b)=>a+b
sum(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+b
sum(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);
// 第一个参数设置默认值, 应用默认调用的时候必须传 undefiend
function 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默认为public
class 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

接口

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理