TypeScript

准备工作:
本地写ts文件,要安装ts编译器:  ts环境
        npm i -g typescript
        tsc
-v      
        tsc hello.ts       --------------> 生成对应.js文件
         每次需要重新编译,再看效果,方法:安装ts-node包:npm i -g ts-node   

手动编译执行:这个包在ts内部转换成js 直接执行js文件:
                ts-node xx.ts   -------> 直接运行ts文件
vscode自动编译ts:全局监听

                创建tsconfig.json, 通过tsc --init 生成配置文件
                打开注释outDir: './js'
                (原理就是tsc -p d:\xxx --watch )
浏览器引用ts文件,时刻监听ts,实时刷新浏览器页面:
                tsc xx.ts   // tsc 生成js
                页面引用js
                tsc --watch xx.ts //实时监听这个文件变化
                live serve 实时监听html页面变化-vscode插件

本地写ts文件,调试:-vscode

// vscode ts断点调试

// 第一步: 添加配置
// 第二步: 在当前目录下 npm i ts-node typescript 这2个包
           原因:全局安装过不够 必须在当前目录下再安装一遍 才能运用到调试中。。。--巨坑!!!

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    
    "version": "0.2.0",
    "configurations": [


        {
            "name": "chrome-htm", //运行html文件,用谷歌浏览器打开
            "type": "chrome",
            "request": "launch",
            "url": "${file}",
            "sourceMaps": true,
            "webRoot": "${workspaceRoot}"
        },
        {
            "name": "node-ts", //单独调试js,即可以直接运行js
            "type": "node",
            "request": "launch",
            "args": ["${workspaceFolder}/hello.ts"], // 要调试的ts文件
            "runtimeArgs": [ // 调试时 加载ts-node包 '直接'运行ts代码
                "-r", "ts-node/register"
            ]
        }
    ]
}

npm i ts-node typescript // 本地生成node-modules文件夹

打断点-点运行-进断点了!!!!

js是动态类型语言,typescript是静态类型语言,是js的超集。类型声明
                                所以ts文件内类型解析失败,也是可以tsc ts文件成js文件


tpyescript-类型声明:

1.基本类型声明:let a: 基本数据类型 = 基本数据

let a: number = 2  => let a = 2
function sum(a: numer, b: number): number {.........}  sum(1, 2)

2.字面量:let a: 基本数据

let a: 2

3.联合类型: let a: string | number

let a: string | number

4.断言
let str:any
str as string

5.函数返回值 Void Never

Void表明函数内return了null/undefined
Never只要用来包裹报错函数的

6.对象的类型注解
let obj: {name: string; age: number; sayHi(): string}
对象的约束-interface
interface IUser {
    name: string
    sayHi: () => void
}

let obj1: IUser = {
    name: '',
    sayHi: () => {...}
}

7.enum 枚举 只读,不能set
enum Gender {
    Male,
    Female
}

let objPerson: Gender
objPerson = Gender.Female



------------node 环境:终端

node xx.js  ----> 在cmd / 终端 中,直接执行js文件 
tsc xx.ts  -----> 在cmd中运行,终端不行:powershell禁止输入

           WINDOWS                                 其他系统上叫terminal,比如mac上
       cmd command line

          \||/--升级版

       powershell-文件夹中按住shift 鼠标右击     mac上在桌面上按command+空格,能弹出搜索框搜terminal/终端

cmd可以运行编译,vscode的终端中运行报错-tsc : 无法加载文件 C:\Users\MLH\AppData\Roaming\npm\tsc.ps1,因为在此系统上禁止运行脚本
因为powershell的执行策略改成RemoteSigned
https://www.jianshu.com/p/7a8ece1bba7f

-------------     vscode 插件配置

// vscode 插件配置

1.设置快捷键log javascript.json
{
	// Place your snippets for javascript here. Each snippet is defined under a snippet name and has a prefix, body and 
	// description. The prefix is what is used to trigger the snippet and the body will be expanded and inserted. Possible variables are:
	// $1, $2 for tab stops, $0 for the final cursor position, and ${1:label}, ${2:another} for placeholders. Placeholders with the 
	// same ids are connected.
	// Example:
	"Print to console": {
		"prefix": "log",
		"body": [
			"console.log('$1')",
			"$2"
		],
		"description": "Log output to console"
	}
}


2.设置html页面自动刷新  安装插件Live serve


3.vscode 窗口背景图 安装插件background  setting.json
{
    "workbench.iconTheme": "vscode-icons",
    "eslint.codeAction.showDocumentation": {
        // 设置 eslint 保存时自动修复
        "eslint.autoFixOnSave": true,
    },
    "workbench.colorCustomizations": {
        "terminal.background":"#292D3E",
        "terminal.foreground":"#959DCB",
        "terminalCursor.background":"#959DCB",
        "terminalCursor.foreground":"#959DCB",
        "terminal.ansiBlack":"#292D3E",
        "terminal.ansiBlue":"#82AAFF",
        "terminal.ansiBrightBlack":"#676E95",
        "terminal.ansiBrightBlue":"#82AAFF",
        "terminal.ansiBrightCyan":"#89DDFF",
        "terminal.ansiBrightGreen":"#C3E88D",
        "terminal.ansiBrightMagenta":"#C792EA",
        "terminal.ansiBrightRed":"#F07178",
        "terminal.ansiBrightWhite":"#FFFFFF",
        "terminal.ansiBrightYellow":"#FFCB6B",
        "terminal.ansiCyan":"#89DDFF",
        "terminal.ansiGreen":"#C3E88D",
        "terminal.ansiMagenta":"#C792EA",
        "terminal.ansiRed":"#F07178",
        "terminal.ansiWhite":"#959DCB",
        "terminal.ansiYellow":"#FFCB6B"
    },
    "editor.tokenColorCustomizations": {
        "editor.background": "#C792EA",
    },
    "terminal.integrated.automationShell.windows": "",
    "terminal.integrated.shell.windows": "D:\\360Downloads\\tools\\Git\\git-cmd.exe",
    "window.zoomLevel": 0,
    "background.enabled": true,
    "background.useDefault": false,
    "background.customImages": [
    "file:///D:/img.jpeg"
    ],
    "background.style": {
    "content": "''",
    "pointer-events": "none",
    "position": "absolute",
    "z-index": "99999",
    "width": "100%",
    "height": "100%",
    "background-position": "center",
    "background-repeat": "no-repeat",
    "background-size": "100%,100%",
    "opacity": 0.2
    },
    "powermode.enabled": true,
    "powermode.presets": "flames",
    "backgroundCover.imagePath": "d:\\img.jpeg"
}


4.设置vscode断点配置 launch.json
{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    
    "version": "0.2.0",
    "configurations": [
        {
            "name": "chrome-htm", //运行html文件,用谷歌浏览器打开
            "type": "chrome",
            "request": "launch",
            "url": "${file}",
            "sourceMaps": true,
            "webRoot": "${workspaceRoot}"
        },
        {
            "name": "node-ts", //单独调试js,即可以直接运行js
            "type": "node",
            "request": "launch",
            "args": ["${workspaceFolder}/hello.ts"],
            "runtimeArgs": [
                "-r", "ts-node/register"
            ]
        }
    ]
}

5.直接运行ts代码 安装插件run code ,只是不能打断点


ts-类型:
number string boolean
array object function [参数-默认参数,可选参数,重载:参数不同走的方法不同]
tuple enum【会自动加1】
 

es5: 静态方法 Person.getInfo()直接调用 static定义的方法不能改变
实例方法 需要new再调用

构造函数实现继承的方法:es5
1.call(),  只能继承实例方法,不能继承实例方法外的原型链上的方法
2.原型链继承: Other.prototype = new Home()

// 继承 .call

function Home() { // 实例一
    this.family = 'tom'
    this.total = 8
    this.sayHi = function () {
        return 'hello~'
    }
}


function Other() {
    Home.call(this)
}

Home.prototype.run = function() {
    return 'running'
}

                                        // let home = new Home() 直接使用,不用造实例

let other = new Other()
other.sayHi()
other.run() // 报错,other.run is not a function


通过call方法实现的继承,不能继承此实例的原型链上的方法,只能继承实例上定义的方法和属性

// 原型链继承


function Home() { // 实例一
    this.family = 'tom'
    this.total = 8
    this.sayHi = function () {
        return 'hello~'
    }
}

Home.prototype.run = function() {
    return 'running'
}

function Fn1 () {}

Fn1.prototype = new Home()

let fn1 = new Fn1()

fn1.run() // running~


//缺点: 实例带参数

function Fn(name, age) {
    this.name = name
    this.age = age
    this.run = function() {
        return age +'岁的'+  name + '在running~'
    }
} 

function Fn4(name, age) {
   // Fn.call(this, name, age)
}

Fn4.prototype = new Fn()
// 也可以 Fn4.prototype = Fn.prototype

let fn4 = new Fn4('tom', 20)

console.log('fn4-run', fn4.run())  // undefined 在running


用call+原型继承解决



构造函数实现继承: es6

// es6定义类

class Person {
    public name: string;
    constructor(n: string) { // 实例化时 触发的函数
        this.name = n
    }
    run():void {
        console.log(this.name + ' running~');
    }
    getName(): string {
        return this.name
    }
    setName(v: string): void {
        this.name = v
    }
}

let p = new Person('tom')
p.run()
console.log(p.getName());

p.setName('cat')

console.log(p.getName());
// es6实现继承

class Table {
    public name: string
    constructor(n: string) {
        this.name = n
    }
    run (): string {
        return `${this.name}` + '在跑步..'
    }
}

let table = new Table('tom')
console.log(table.run());

class Web extends Table{
    constructor(name: string) {
        super(name) // 初始化 父类的构造函数
    }
}

let web = new Web('李四')
console.log(web.run());

es6 class类中修饰符

public: 类、子类、类外调用 都能访问
protected: 类、子类可调用,类外不能调用
private: 只在自己类内可调用

属性不加修饰符,默认就是公有-public

es6 class类中的静态属性 静态方法
 

// es6 中定义 静态属性 静态方法


class Bag {
    public name: string
    static name1: any = 'cat';
    constructor(name: string) {
        this.name = name
    }
    run(): string {
        return `${this.name} 身上有个bag`
    }
    static work(): string {
        return `${this.name1}在work`
    }
}

let bag = new Bag('tom')
console.log(bag.run()); // 实例方法
console.log(Bag.name1); // 不通过new的方式,直接对象点访问的,叫静态属性
console.log(Bag.work()); // 方法属性




类的多态概念:
  父类定义一个方法不去实现,让继承他的子类去实现,每个子类有不同的实现/表现
  多态属于继承,是继承的一种表现

// 多态: 父类不去实现,子类有不同的实现

class Car {
    type: string
    constructor(type: string) {
        this.type = type
    }

    oil() {

    }
}

class WeiLai extends Car{
    constructor(type: string) {
        super(type)
    }

    oil(): string {
        return `${this.type}`
    }
}

let weilai = new WeiLai('柴油')

console.log(weilai.oil());



class DaZhong extends Car{
    constructor(type: string) {
        super(type)
    }

    oil():string {
        return `${this.type}`
    }
}

let dazhong  = new DaZhong('机油')
console.log(dazhong.oil());


ts抽象类: 规范子类,提供其他类的继承基类,不能被直接实例化
用 关键字abstract定义抽象类和抽象方法,
抽象类中的抽象方法不包含具体实现方法, 并且必须在派生类中实现

// 抽象方法 只存在于抽象类中


abstract class Car {
    type: string
    constructor(type: string) {
        this.type = type
    }

    abstract oil(): any
}


class DaGi extends Car{
    constructor(type: string) {
        super(type)
    }
    oil(): string{
        return this.type
    }
}

console.log('------------------------------Car类中,要求派生类中必须包含oil这个方法');

let daGi = new DaGi('大G')
console.log(daGi.oil());

接口: 规范属性,方法,函数,可索引
Interface 
abstract 定义子类的标准
 


// 属性类接口:函数参数的规范-接口
    // 可批量使用interface



// ​​​​​​​数组/对象类接口:
interface arrInter {
    // index         value => any类型
    [index: number]: string
}

可使用:   let arr: arrInter = ['name': 'tom']

也可使用: {...} as arrInter

// 类类型接口:对类的约束 和抽象类有点类似
interface Animal {
    name: string
    eat(): void
}


class Dog implements Animal {  // implements 实施
    name: string
    constract(name: string) {
        this.name = name
    }
    
    eat() {
        console.log('dog吃肉肉')
    }
}

let dog = new Dog('dog')
console.log(dog.eat())


//class 实现继承 + 类类接口继承
interface Person extends Animal {
  work(): void
}

class Programer {
  name: string
  constructor(name: string) {
    this.name = name
  }
  coding() {
    console.log('coding-父类');
  }
}

class Pwork extends Programer implements Person {  // 重点!!
  constructor(name: string) {// 重点!!
    super(name)
  }
  eat() {
    console.log('人类吃米饭');
  }
  work() {
    console.log('人类工作');
  }
  money() {
    return `${this.name}能花钱`
  }
}

let p1 = new Pwork('人')
console.log(p1.eat(), p1.work(), p1.money(), p1.coding());







泛型: 传什么类型,返回什么类型
any: 
               ():string                   {}
const fn: () => string = () => {return '111'}


// 泛型的定义 泛型函数
function getData<T>(value: T): T {
    return value
}

getData<number>(1)
getData<string>('1')



function getData<T>(value: T): any {
    return '1111'
}

getData(1)
getData("1")



// 泛型类

class Minclass<T> {
  public list: T[] = []
  add(v: T): void {
    this.list.push(v)
  }
  min(): T {
    let one = this.list[0]
    for (let i: number = 0; i< this.list.length; i++) {
      if (one > this.list[i]) {
        one = this.list[i]
      }
    } 
    return one;
  }
}

let min = new Minclass<number>()
min.add(2)
min.add(22)
min.add(12)
console.log(min.min());


let minstr = new Minclass<string>()
minstr.add('20')
minstr.add('22')
minstr.add('33')
console.log(minstr.min());



// 类作为参数约束传入的参数

class User {
    public uname: string | undefined
    public pwd: string | undefined
}

class MysqlDb {
    add(user: User):boolean {
        return true
    }
}

// let mysqlDb = new MysqlDb()
// console.log(mysqlDb.add({uname: 'tom', pwd: '123'}));

let u = new User()
u.uname = 'tom'
u.pwd = '123'

let mDb = new MysqlDb()
console.log(mDb.add(u));


// 类作为参数约束传入的参数 -改成泛型: 避免代码重复+对不特定类型进行校验
// 泛型类 对传入的数据进行校验

class User {
    public uname: string | undefined
    public pwd: string | undefined
}

class MysqlDb<T> {
    add(user: T):boolean {
        console.log(user);
        return true
    }
}

// let mysqlDb = new MysqlDb()
// console.log(mysqlDb.add({uname: 'tom', pwd: '123'}));

let u = new User()
u.uname = 'tom'
u.pwd = '123'

let mDb = new MysqlDb<User>() // 类型校验是User
console.log(mDb.add(u));











// 给类分组  命名空间namespace
// x.ts

namespace A {

    export class Aclass {....}

    export let name = ...

}

namespace B {

    export class Aclass {....}

    export let name = ...

}

// 在内部使用: 

let a = new A.Aclass()
let b = new B.Aclass()

.....

// 暴露出去 

export namespace A {

    export class Aclass {....}

    export let name = ...

}

 // 引用A
  // 方法一

import { A } from 'x.ts'

let a = new A.Aclass()

...

  // 方法二-不推荐

/// <reference path='x.ts' />


装饰器:对不改变类时的拓展
装饰器执行顺序:
     属性 > 方法 > 方法参数 > 类 
​​​​​​​     多个相同的装饰器,从后往前执行

 


// 装饰器
    // 类装饰器 无参 传参-装饰器工厂
function deFn(p1: string) {

    console.log('1--', p1);
    
    return function(param: any) {  // 装饰器工厂

        console.log(param, '2--', p1);
        param.prototype.name = '类装饰器'
        param.prototype.otherName = p1
        param.prototype.eat = () => {
            console.log('类装饰器-eat')
        }
    }
}
        
                // 紧贴着class 不能有分号
@deFn('tom')    // -类装饰器表达式 会在运行时被当做函数调用, 类的构造函数作为其唯一的参数 
class DeClass {

    constructor() { // -类的构造函数
    
    }

    getData():void {

        console.log('getData');

    }   
}

let de: any = new DeClass() // : any 去掉就报错

console.log(de.name);

de.eat()

de.getData()

console.log(de.otherName);




    // 类装饰器 重载类构造器的属性和方法: 拓展或替换当前类[DeClass]的构造函数

function deFn(p1: string) {

    return class extends DeClass { // 继承DeClass 一定要带上类的所有属性和方法,不然会报错

        name: string = 'name重载'

        getData(): void {

            console.log('getData重载')

        }
    }
}

@deFn()
class DeClass {

    public name: string | undefined

    constructor() { // -类的构造函数
    
    }

    getData():void {

        console.log('getData', this.name);

    }   

}

let de: any = new DeClass() // : any 去掉就报错



// 方法参数装饰器

function logParams(pas: any) {
    // paramIndex 参数在参数数组中的下标
    return function(target: any, methodNameA: any, paramIndex: number) {
        console.log(target, methodNameA, paramIndex);
        
    }
}


class AnimalFn {
    @logAnimal('XXX-name')
    public name: string | undefined

    @logAnimal(20)
    public age: number | undefined

    constructor() {}

    @logFn('methods')
    getName(...any: any[]): void {
        console.log('getName-我是', any)
    }

    // 方法参数装饰器
    getDataA(@logParams('uuid') uuid: string): void {
        console.log('logParams', uuid);
    }
}

let aFn = new AnimalFn()
aFn.getName(12, 'xxx')




ts常见报错:

类型“DeClass”上不存在属性“name”:   
                        ->    let de: any = new DeClass()
    let de = new DeClass()
    console.log(de.name);

属性“age”没有初始化表达式,且未在构造函数中明确赋值: 
                        -> public age: number | undefined
    public age: number


已声明“target”,但从未读取其值
参数“target”隐式具有“any”类型:
                        -> function A (target: any){}
    function A (target) {}


function A(target: any): typeof (Anonymous class)
作为表达式调用时,无法解析类修饰器的签名。
  不能将类型“typeof (Anonymous class)”分配给类型“typeof Animal”。
    Property 'getName' is missing in type '(Anonymous class)' but required in type 'Animal'.ts(1238)
decorator.ts(62, 5): 'getName' is declared here.
                        -> 
报错实例:
function A (target: any) {
    console.log(target);
    return class extends target {
        name: any = '我是extends edit-name'
        // constructor() {
        //     super()
        //     this.name = 'edit-name'
        // }
        // 解决-getName 也要重载一下

    }
}


@A // error 红波浪线
class Animal {
    public name: string | undefined
    constructor() {
        this.name = '我是构造函数animal -小动物'
    }

    getName() {
        console.log('getName', this.name);
    }
}

let animal = new Animal()
console.log(animal.name);

animal.getName()




                                        


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值