TypeScript (二)

151 阅读2分钟

联合类型和类型保护

interface Bird {
    fly: boolean;
    sing: () => {}
}
interface Dog {
    fly: boolean;
    bark: () => {}
}
// 类型断言的方式
function demo(animal: Bird | Dog) {
    if(animal.fly){
        (animal as Bird).sing()
    }else {
        (animal as Dog).bark()
    }
}

// in 语法来做类型保护
function demo1(animal: Bird | Dog) {
    if("sing" in animal) {
        animal.sing()
    }else {
        animal.bark()
    }
} 

// typeof 语法来做类型保护
function add(first: string | number, second: string | number) {
    if(typeof first === "string" || typeof second === "string") {
        return `${first}${second}`
    }
    return first + second
}

// 使用 instanceof 语法来做类型保护
// 只有类才具有instanceof ,不能用interface
// instanceof 用于判断一个变量是否某个对象的实例
class NumberObj {
    count: number
}
function add(first: object | NumberObj, second: object | NumberObj) {
    if(first instanceof NumberObj && second instanceof NumberObj) {
        return first.count + second.count
    }
    return 0
}

枚举类型 Enum

  • npm install typescript --save
  • npm install ts-node -D
package.json
"scripts": {
    "dev": "ts-node ./demo.ts"
} 

// 枚举
enum Status {
    OFFLINE,     // 0
    ONLINE = 3,      // 3
    DELETED      // 4
}
赋值是按顺序,默认0开始
Status[0] = OFFLINE
Status[3] = ONLINE
Status[4] = DELETED

函数泛型 , 泛指的类型

function join<ABC>(first:ABC, second:ABC) {
    return `${first}`
}
join<number>(1, 1)

function join<T, P>(first:T, second:P) {
    return `${first}${second}`
}
join<number, string>(1, "100")
join(1, "100")    // 也可以这样,不写具体类型与泛型匹配,他会自己推断

类中的泛型以及泛型类型

interface Item {
    name: string
}
class DataManager<T extends Item>{
    constructor(private data: T[]) {}
    getItem(index: number): string {
        return this.data[index].name;
    }
}

const data = new DataManager([{name: "jack"}])
class DataManager<T extends number | string>{
    constructor(private data: T[]) {}
    getItem(index: number): T {
        return this.data[index];
    }
}
const data = new DataManager<number>([])
// 如何使用泛型作为一个具体的类型注解
function hello<T>(params: T){ return params }

const func: <T>(params: T) => <T> = hello;

命名空间

  • tsc -w 这命令是监听 .ts 文件,每次.ts文件有变动的时候,自动编译
你把所有东西放到Home这个命名空间里面,
有些东西不想暴露出去,只想暴露出去某些东西,Page就不能直接拿了
namespace Home {
    class Header {…… ……}
    class Content {…… ……}
    class Footer {^ ^}
    
    export class Page {
        new Header()
        new Content()
        new Footer()
    }
}

// 命名空间也可以套命名空间,里面也可以写interface
namespace Components {
    export namespace SubComponent {
        export class Test {}
    }
    
    export interface User {
        name: string
    }
}

使用parcel打包TS代码,这个编译器会分析如果html引入.ts文件,它会自动帮我们把.ts编译,然后编译成浏览器可以运行的代码, 把这个.ts文件会生成一个.js文件

  • npm install parcel@next -D
<html>
    <script src="./page.ts"></script>
</html>

在package.json 里使用
{
    "scripts": {
        "test": "parcel ./src/index.html"
    }
}

描述文件中的全局类型

  • 新建 jquery.d.ts文件【类型描述文件】帮助我们去理解对应的 .js 文件
declare:解释或者描述一个全局变量
declare var $: (param: () => void) => void;

定义全局函数
interface JqueryInstance {
    html: (html:string) => JqueryInstance
}
declare function $(readyFunc: () => void): void;
declare function $(selector:string): JqueryInstance;

// 如何对对象进行类型定义,以及对类进行类型定义,以及命名空间的嵌套
declare namespace $ {
    namespace fn {
        class init{}
    }
}

// 使用 interface 的语法,实现函数重载
interface JQuery {
    (readyFunc: () => void): void;
    (selector:string): JqueryInstance;
}
declare var $: JQuery;

模块代码的类型描述文件

由于 install jquery 并没有ts的描述文件,我们要手动描述

import $ from "jquery";
$(function (){
    $("body").html("<div>111</div>")
    $.fn.init()
})

// ES6模块化
declare module "jquery" {
    interface JqueryInstance {
        html: (html:string) => JqueryInstance
    }
    // 混合类型
    function $(readyFunc: () => void): void;
    function $(selector:string): JqueryInstance;
    namespace $ {
        namespace fn {
            class init{}
        }
    }
    
    export = $;
}

泛型中 keyof 语法的使用

要有类型保护

const name = teacher.getInfo("name") as string    // 返回的是string类型
interface Person {
    name: string;
    age: number;
    gender: string;
}
class Teacher {
    constructor(private info: Person) {}
    getInfo<T extends keyof Person>(key: T): Person[T] {
        return this.info[T]
    }
}
const teacher = new Teacher({
    name: 'jack',
    age: 25,
    gender: 'male'
})
const test = teacher.getInfo("name")

结语

前端react QQ群:788023830 ---- React/Redux - 地下老英雄

前端交流 QQ群:249620372 ---- FRONT-END-JS前端

(我们的宗旨是,为了加班,为了秃顶……,仰望大佬),希望小伙伴们加群一起学习