zoukankan      html  css  js  c++  java
  • TypeScript——类型检查机制

    类型检查机制:TypeScript编译器在做类型检查时,所秉承的一些原则,以及表现出的一些行为。

    作用:辅助开发,提高开发效率。

    类型推断

    :指不需要指定变量的类型(函数的返回值类型),TypeScript可以根据某些规则自行的推断出一个类型

    1.基础类型推断
    2.最佳通用类型推断
    3.上下文类型推断

    - 前两者都是从右往左的推断,根据值去推断, 例如 let a = 1 // a 被推断的类型是 number

    let a = 1

    - 最佳通用类型推断 例如 let b = [1, 'a'] // b 的最佳通用类型 (string | number)[]

    let b = [1, 'a']
    let c = (x = 1) => x + '2' // function(x: number): string

    - 根据上下类型推断 例如 window.onkeydown = (event) => {} // 推断 event 为 KeyboardEvent

    window.onkeydown = (event) => {
        console.log(event)
    }

    关于类型断言

    interface Foo {
        bar: number
    }
    let foo = {} as Foo
    foo.bar = 1
    /**
     * 以上使用`as`的方式,不会提示是否缺失定义`bar`属性,
     * 最好的方式是使用下面代码,在定义时就指明类型
     * 
     * Property 'bar' is missing in type '{}' but required in type 'Foo'.
     */
    
    let foo02 : Foo = {
        bar: 1
    }

    类型兼容性:(当一个类型Y可以被赋值给另一个类型X时,可以说类型X兼容类型Y) =》X(目标类型)=Y(源类型)

    • 口诀
              结构之间兼容:成员少的兼容成员多的
              函数之间兼容:参数多的兼容参数少的
    • 接口兼容性:成员少 兼容 成员多的(前提:源类型具备目标类型的必要属性 则可以向其兼容)
    interface X {
        a: number;
        b: number;
    }
    interface Y {
        a: number;
        b: number;
        c: number;
    }
    let xx: X = { a: 1, b: 2}
    let yy: Y = { a: 1, b: 2, c: 3 }
    // yy = xx // Property 'c' is missing in type 'X' but required in type 'Y'
    xx = yy // Ok
    • 函数兼容性
    type Handler = (a: number, b: number) => void
    function hof(handler: Handler) {
        return handler
    }
    // 1.参数个数
    let handler1 = (a: number) => {}
    hof(handler1)
    let handler2 = (a: number, b: number, c: number) => {}
    // hof(handler2) // 源函数参数3个 而目标函数参数2个 所以不能达到兼容
    
    // 可选参数和剩余参数
    let a1 = (p1: number, p2: number) => {}
    let b1 = (p1?: number, p2?: number) => {}
    let c1 = (...arg: number[]) => {}
    // 固定参数可兼容可选/剩余
    // a1 = b1
    // a1 = c1
    // 可选参数不可兼容固定/剩余 改变"strictFunctionTypes"为 false可进行兼容
    // b1 = a1
    // b1 = c1
    // 剩余参数可兼容可选/固定
    c1 = a1
    c1 = b1
    
    // 2.参数类型
    // 简单类型
    let handler3 = (a: string) => {}
    // hof(handler3) // 类型不兼容
    
    // 复杂类型(对象)
    interface Point3D {
        x: number;
        y: number;
        z: number;
    }
    interface Point2D {
        x: number;
        y: number;
    }
    let p3d = (point: Point3D) => {};
    let p2d = (point: Point2D) => {};
    p3d = p2d
    // p2d = p3d // 成员多 兼容 成员多少的 改变"strictFunctionTypes"为 false可进行兼容
    
    /* 3.返回值类型 Ts要求函数定理类型与返回值类型相同或为其子类型
     * 少的可以兼容多的
    */
    let f1 = () => ({ name: 'jessiex' })
    let f2 = () => ({ name: 'jessiex', age: '2' })
    f1 = f2
    // f2 = f1 // 无法兼容
    • 枚举类型
    enum Fruit { Apple, Banana }
    enum Color { Red, Yellow }
    let fruit: Fruit.Apple = 3
    let no: number = Fruit.Apple // 枚举与number之间是相互兼容的
    // let color: Color.Red = Fruit.Apple // 枚举之间相互不兼容
    • 类类型
    // 比较两个类是否兼容时,静态成员和构造函数是不参与比较的
    class A {
        constructor(p: number,q:number) {}
        id: number = 1
        private name: string = ''
    }
    class B {
        static s =1
        constructor(p: number) {}
        id: number = 2
    }
    let aa = new A(1,2)
    // let bb = new B(1)
    // aa = bb OK
    // bb = aa OK
    // 在拥有私有成员时,只有父类和子类之间相互兼容
    class C extends A {}
    let cc = new C(1,2)
    cc = aa // (aa=bb)Fail
    aa = cc // (bb=bb)Fail 

    类型保护

      指TS能够在特定的区块中保证变量属于某种确定的类型。可以再次区块中放心的引用此类型的属性,或者调用此类型的方法

    enum Type { Strong, Weak }
    class Java {
        helloJava() {
            console.log('hello,Java')
        }
        java: any;
    }
    class JavaScript {
        helloJavaScript() {
            console.log('hello,JavaScript')
        }
        js: any;
    }
    function isJava(lang: Java|JavaScript): lang is Java {
        return (lang as Java).helloJava !== undefined
    }
    function getLanguage(type: Type, x: string | number) {
        let lang = type === Type.Strong ? new Java() : new JavaScript();
        // 1.instanceof 通过判断一个实例是否属于某个类
        if (lang instanceof Java) {
            lang.helloJava()
        } else {
            lang.helloJavaScript()
        }
        // 2.in 通过判断一个属性是否属于某个对象 
        if ('java' in lang) {
            lang.helloJava()
        } else {
            lang.helloJavaScript()
        }
        // 3.typeof 通过判断一个变量的类型(借助变量x示范)
        if (typeof x === 'string') {
            console.log(x.length)
        } else {
            x.toFixed(2)
        }
        // 4.类型保护函数:某些判断可能不是一条语句能够搞定的,需要更多复杂的逻辑,适合封装到一个函数内
        if (isJava(lang)) {
            lang.helloJava()
        } else {
            lang.helloJavaScript()
        }
        return lang;
    }


      

  • 相关阅读:
    bootstrap 弹出框(Popover)插件 修改title等属性选项值
    dedecms 搬家流程
    jQuery ui 百叶窗blind方向设置
    css 优先级
    dedecms 标签
    dedecms 建站相关问题
    css 透明度使用
    css 边框使用
    css 阴影使用
    js 常用判断
  • 原文地址:https://www.cnblogs.com/JessieXie/p/12384960.html
Copyright © 2011-2022 走看看