最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 1-02-02 TS介绍及JS类型检查

    正文概述 掘金(红尘灬客栈)   2021-03-24   611
    1. TypeScript 大大提高代码的可靠程度
    2. JavaScript 自有类型系统的问题

    介绍TypeScript前先介绍一下类型检查

    介绍模块

    1. 强类型与弱类型
    2. 静态类型与动态类型
    3. JavaScript 自有类型系统的问题
    4. Flow静态类型检查方案
    5. TypeScript语言规范与基本应用

    1. 类型介绍

    1. 强类型 vs 弱类型

    1. 强类型: 语言层面限制函数的实参类型必须与形参类型相同

    eg:

    class Main {
        static void foo(int num) {
            System.out.println(num);
        }
        
        public static void main(String[] args) {
            Main.foo(100); // ok
            
            Main.foo("100"); // error "100" is a string
            
            Main.foo(Integer.parseInt("100 ")); // ok
        }
    }
    
    1. 弱类型:语言层面不会限制实参的类型

    eg

    function foo(num) {
        console.log(num)
    }
    foo(100) // ok
    foo('100') // ok
    foo(parseInt('100')) // ok
    
    个人理解:
    1. 强类型语言中不允许什么问题的隐式类型转换
    2. 弱类型语言则允许任意的数据隐式类型转换
    3. 强类型不允许随意的隐式类型转换,而弱类型是允许的
    4. 变量类型允许随时改变的特点,不是强毕竟类型的差异

    2. 类型系统

    1. 静态类型: 一个变量声明时它的类型就是明确的,声明过后,它的类型就不允许修改了
    2. 动态类型:在运行阶段才能够明确变量类型,而且变量的类型随时可以改变

    eg:

    var foo = 100
    foo = 'bar' // ok
    console.log(foo)
    

    也可以说在动态类型语文中的变量没有类型,而变量中存放的值是有类型的

    类型安全分为 强类型弱类型

    类型检查分为 静态类型动态类型

    如下图 1-02-02 TS介绍及JS类型检查

    2.1 JavaScript 类型系统特征

    js的类型用一个词描述:【任性 缺失了类型系统的可靠性 --> 不靠谱

    ? 为什么JavaScript不是强类型 / 静态类型
    1. 早前的 JavaScript 应用简单
    2. JavaScript 没有编译环节
    3. 选择为 弱类型 / 动态类型
    4. 在大规模应用下,这种【优势】就变成了短板
    

    弱类型的问题

    // 01
    const obj = {}
    obj.foo()
    // 报错要等到运行阶段才能发现类型异常
    // ======================
    // 02
    function sum(a, b) {
        return a + b
    }
    console.log(sum(100, 100)) // 200
    console.log(sum(100, '100')) // 100100
    // ======================
    // 03
    const obj = {}
    obj[true] = 100 // 会自动转换成字符串
    
    console.log(obj['true'])
    

    强类型的优势

    1. 错误更早暴露
    2. 代码更智能,编码更准确
    3. 重构更牢靠
    4. 减少不必要的类型判断
    5. ......

    2. Flow js的类型检查工具

    Flow

    Flow只是一个小工具,So Easy

    // 类型注解
    function sum (a: number, b: number) {
        return a + b
    }
    sum(100, 50) // ok
    sum('100', 50) // error
    

    快速上手

    // 安装 yarn add flow-bin --dev
    
    // 增加.flowconfig文件 yarn flow init
    /*
    .flowconfig
    [ignore]
    [include]
    [libs]
    [lints]
    [options]
    [strict]
    */
    
    // 使用的时候需要在文件顶上增加 @flow,并且需要关闭掉vscode的语法校验
    // @flow
    function sum (a, b) {
        return a + b
    }
    
    // 终端使用命令检查 
    // 执行 yarn flow
    // 停止 yarn flow stop
    

    编译

    • 写好的js文件没办法用node执
    // 所以安装 yarn add flow-remove-types --dev
    
    // 执行 yarn flow-remove-types [文件目录] . -d [输出目录]
    
    
    尝试使用babel
    // @babel/core 核心模块
    // @babel/cli cli工具,可以让我们在命令行中直接使用babel命令去完成编译
    // @babel/preset-flow --dev
    // 安装
    // yarn add @babel/core @babel/cli @babel/preset-flow --dev
    
    // 2. 添加babel的配置文件 .babelrc
    /*
    // .babelrc
    {
        "presets": ["@babel/preset-flow"]
    }
    
    */
    // 执行命令 yarn babel src -d dist
    
    

    开发工具插件 Flow Lanugage Support

    • 下载插件 Flow Lanugage Support

    类型推断 Type Inference

    /**
    * 类型推断
    * @flow
    */
    function square (n) {
        return n * n
    }
    square('100') // 这里用了字符串,flow会推导出 n*n是错误的
    

    类型注解 Type Annotations

    // 1. 函数的参数上以及返参
    funcion square(n:  number): number {
        return n * n
    }
    // 2. 变量
    let num: number = 100;
    
    // 3. 没有返回值标记成void
    function say(): void {}
    

    原始类型 Primitive Types

    let a: string = 'foobar'
    
    let b: number = Infinity // NaN // 100
    
    let c: boolean = true
    
    let d: null = null
    
    let e: void = undefined
    
    let f: symbol = Symbol()
    

    数组类型 Array Types

    // 泛型
    const arr1: Array<number> = [1, 2, 3]
    
    const arr2: number[] = [1, 2, 3]
    
    // 元组
    const f00: [string, number] = ['foo', 100]
    

    对象类型 Object Types

    const obj1: {foo: string, bar: number} = { foo: 'string', bar: 100 }
    
    const obj2: {foo?: string, bar: number} = {bar: 100}  // foo可选
    
    const obj3: {[string]: string} = {}
    obj3.key1 = 'value1'
    obj3.key2 = 'value2'
    

    函数类型 Function Types

    
    function foo(callback: (string, number) => void) {
        callback('string', 100)
    }
    
    foo(function(str, n) {
        // str => string
        // n => number
    })
    

    特殊类型

    
    // 字面量类型
    const a: 'foo' = 'foo' // a变量只能为 foo字符串
    
    const type: 'success' | 'warning' | 'danger' = 'success'
    
    const b: string | number = 100 // 'string'
    
    type StringOrNumber = string | number
    
    const c: StringOrNumber = 'string' // 100
    
    // maybe 类型
    const gender: ?number = null // undefined // number
    // 上面等价于下面这个
    const gender: number | null | void = undefined // null // number
    
    

    Mixed & Any 任意类型

    // mixed 就是所有类型 ==> string | number | boolean | ....
    function passMixed(value: mixed) {
        
    }
    passMixed('string')
    passMixed(100)
    
    // -----------------------
    
    function passAny(value: any) {
        
    }
    passAny('string')
    passAny(100)
    
    // 区别是  any是弱类型  mixed是强类型
    function passMixed(value: mixed) {
        value.substr(1)
        value * value
        // 这里会提示报错
        // 改成下面
        if (typeof value == 'value') {
            value.substr(1)
        }
        if (typeof value == 'number') {
            value * value
        }
    }
    passMixed('string')
    passMixed(100)
    
    // -----------------------
    
    function passAny(value: any) {
        value.substr(1)
        value * value
    }
    passAny('string')
    passAny(100)
    
    

    类型小结

    • 官方文档 flow.org/en/docs/typ…
    • 第三方类型手册 www.saltycrane.com/cheat-sheet…

    运行环境API -> 内置对象

    const element: HTMLElement | null = document.getElementById('app') // 这里必须传字符串 传数字会提示报错
    
    // https://github.com/facebook/flow/blob/master/lib/core.js
    // https://github.com/facebook/flow/blob/master/lib/dom.js
    // https://github.com/facebook/flow/blob/master/lib/bom.js
    // https://github.com/facebook/flow/blob/master/lib/cssom.js
    // https://github.com/facebook/flow/blob/master/lib/node.js
    
    

    3. TypeScript

    TypeScript JavaScript的超集 (superset)

    • 功能更为强大,生态也更健全、更完善
    • 开源框架使用ts Angular / Vue.js3.0
    • TypeScript -- 前端领域中的第二语言

    1-02-02 TS介绍及JS类型检查

    TypeScript属于渐进式

    缺点

    1. 语言本身多了很多概念
    2. 项目初期,TypeScript会增加一些成本

    快速上手

    yarn init --yes
    
    yarn add typescript --dev
    
    yarn tsc xxxx.ts
    
    
    // 可以完全按照 JavaScript 标准语法编写代码
    

    配置文件

    compilerOptions
        target: 编译之后的ES版本
        module: 输出的代码采用什么样的方式进行模块化
        lib: 指定所引用的标准库 ["ES2015", "DOM"]
        outDir: 设置编译结果输出到的文件夹 dist
        rootDir: 配置我们源代码的文件夹 src
        sourceMap: 是否开启源代码映射
        strice: 是否开启严格模式
    需要直接运行tsc命令编译整个项目
    yarn tsc
    

    原始类型 Primitive Types

    const a: string = 'foobar'
    
    const b: number = 100 // NaN Infinity
    
    const c: boolean = true // false
    // 以上是在非严格模式下均可设置为 null
    
    const e: void = undefined
    
    const f: null = null
    
    const g: undefined = undefined
    
    const h: symbol = Symbol()
    

    标准库声明

    中文错误信息

    const error: string = 100
    

    作用域问题

    • 解决就是用单独的作用域,可以使用 export {}

    Object 类型 Object Types

    const foo: object = {} // [] // function() {}
    
    // 可以这样定义指定为对象 可以用接口
    const obj = {foo: number } = { foo: 123 }
    

    数组类型 Array Types

    const arr1: Array<number> = [1, 2, 3]
    const arr2: number[] = [1, 2, 3]
    
    // -------------------------
    
    function sum(...args: number[]) {
        return args.reduce((prev, current) => prev + current, 0)
    }
    sum(1, 2, 3)
    
    

    元组类型 Tuple Types

    const tuple:  [number, string] = [18, 'string']
    
    tuple[0]
    tuple[1]
    
    const [age, name] = tuple
    
    // ------------------------
    
    

    枚举类型 Enum Types

    1. 给一组数值去分别取上更好理解的名字
    2. 一个枚举中只会存在几个固定的值,并不会出现超出范围的可能性
    enum OrderStatus {
        WaitPay = 0,
        Pay = 1,
        Cancel = 2
    }
    
    // 枚举的值可以是字符串
    enum OrderStatus {
        WaitPay = 'waitPay',
        Pay = 'pay'
    }
    // 会被编译成以下代码
    var OrderStatus;
    (function (OrderStatus) {
        OrderStatus["WaitPay"] = "waitpay";
        OrderStatus["Pay"] = "pay";
    })(OrderStatus || (OrderStatus = {}));
    
    // 如果枚举的值是数值的,可以这样取 OrderStatus[0]
    
    // 在enum 的前面加上 const
    const enum OrderStatus {
        WaitPay = 0,
        Pay
    }
    // 编译的时候会去掉枚举相关的信息,只留下 0 , 1 , 3
    

    函数类型 Function Types

    function func1(a: number, b: number): string {
        return 'func1'
    }
    // 可选参数 可以设置 a?: number
    
    // -------------------------
    // 函数的表示式
    const func2: (a: number, b: number) => string = function(a: number, b: number): string {
        return 'func2'
    }
    

    任意类型 Any Types

    function stringify(value: any) {
        return JSON.stringify(value)
    }
    

    隐式类型推断 Type Inference

    let age = 18 // 推断为age: number
    
    age = 'string' // 会报错
    
    let foo; // 推断为any
    foo = 100
    foo = 'string'
    // 都是可以的
    
    

    类型断言 Type assertions

    // 假定这个 nums 来自一个明确的接口
    const nums = [110, 120, 119, 112]
    
    const res = nums.find(i => i > 0) // 推导出res 为 number | undefined
    
    // 我们需要告诉Ts,这就是一个number类型
    const num1 = res as number
    const num1 = <number>res  // JSX 下不能使用
    

    接口 Interfaces

    
    interface IPost {
        title: string;
        content: string
    }
    
    function printPost(post: IPost) {
        console.log(post.title)
        console.log(post.content)
    }
    
    • 可选成员、只读成员
    interface IPost {
        title: string;
        content: string;
        subtitle?: string // 可选参数  string | undefined
        readonly summary: string // 不允许修改
    }
    
    // 动态成员
    interface Cache {
        [prop: string]: string
    }
    

    1. ES6以前, 函数 + 原型 模拟实现类
    2. ES6开始 JavaScript中有了专门的class
    3. TypeScript 增强了class 的相关语法
    1. 基本使用
    class Person {
    
        name: string;
        age: number;
    
        constructor(name: string, age: number) {
            this.name = name;
            this.age = age;
        }
    
        sayHi(msg: string) {
            console.log(`I am ${this.name} , ${msg}`)
        }
    }
    
    2. 访问修饰符
    1. private 私有属性,只能在内部用this访问
    2. public public 公有成员
    3. protected 受保护的 不能在外部访问

    protected在子类中使用this是可以访问到的

    3. 只读属性
    // 比如
    public readonly name: string;
    
    4. 类与接口
    // 规定协议 
    
    interface Eat {
        eat(food: string): void
    }
    
    interface Run {
        run(distance: number): void
    }
    
    class Person implements Eat, Run {
        eat(food: string): void {
    
        }
        run(distance: number): void {
    
        }
    }
    
    class Animal implements Eat, Run {
        eat(food: string): void {
    
        }
        run(distance: number): void {
    
        }
    }
    
    5. 抽象类
    export {} // 确保跟其它示例没有成员冲突
    abstract class Animal {
        eat(food: string): void {
            console.log('呼噜呼噜的吃' + food)
        }
        // 定义抽象方法
        abstract run (distance: number): void
    }
    
    class Dog extends Animal {
        run(distance: number): void {
            console.log('四脚爬行', distance)
        }
    }
    const d = new Dog()
    
    6. 泛型 Generics
    function createArray<T>(length: number, value: T): T[] {
        const arr = Array<T>(length).fill(value)
        return arr
    }
    const res = createArray<string>(3, 'foo')
    
    
    7. 类型声明 Type Declaration
    import { camelCase } from 'lodash'
    
    declare function camelCase (input: string): string
    const res = camelCase('hello typed') // 在这里函数没有提示,需要声明 如上
    
    

    引用第三方模块,如果模块中不包含类型声明文件,就需要自己声明


    起源地下载网 » 1-02-02 TS介绍及JS类型检查

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元