美文网首页
笔记四:TypeScript语言

笔记四:TypeScript语言

作者: 油菜又矮吹 | 来源:发表于2020-08-04 21:17 被阅读0次

    一、JavaScript

    1.弱类型、动态语言的缺陷

    • 程序中的异常在运行时才能发现
    • 类型不明确函数功能会发生改变
    • 对对象索引器的错误用法

    2.强类型的优势

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

    二、Flow

    1.Flow是JavaScrpt类型检查器

    // : number 叫做类型注解
    function sum (a: number, b: number) {
      return a + b
    }
    console.log(sum(1, 2))
    

    2.如何安装并使用flow

    • 先执行yarn init -y
    • 执行yarn add flow-bin
    • 在代码中第一行添加flow注释://@flow
    • 在函数中形参后面加上冒号和类型 function sum(a:number, b: number)
    • 执行yarn flow init 创建flowconfig
    • 执行yarn flow
    // @flow
    // : number 叫做类型注解
    function sum (a: number, b: number) {
      return a + b
    }
    console.log(sum(1, 2))
    
    console.log(sum('100', '100'))
    

    3.如何移除flow注解

    flow官方提供的操作

    • yarn add flow-remove-types --dev
    • yarn flow-remove-types src -d dist
      使用babel配合flow转换的插件
    • yarn add @babel/core @babel/cli @babel/preset-flow --dev
    • babel文件
    {
        "presets":["@babel/preset-flow"]
    }
    
    • yarn babel src -d dist

    4.开发工具插件

    5.Flow支持的类型

    /**
     * 原始类型
     * @flow
     */
    
     const a: string = 'foo'
    
     const b: number = Infinity // NaN // 100
    
     const c: boolean = false // true
    
     const d: null = null
    
     const e: void = undefined
    
     const f: symbol = Symbol()
    
     const arr: Array<number> = [1, 2, 3]
    
     const arr2: number[] = [1, 2, 3]
    
     // 元组
     const foo: [string, number] = ['foo', 100]
    
    const obj1: {foo: string, bar: number} = {foo: 'string', bar: 100}
    
    // 问号表示可有可与的属性
    const obj2: {foo?: string, bar: number} = {bar: 100}
    
    // 表示当前对象可以添加任意个数的键,不过键值的类型都必须是字符串
    const obj3: {[string]: string} = {}
    obj3.key1 = 'value1'
    // obj3.key2 = 100
    
    function fn (callback: (string, number) => void) {
      callback('string', 100)
    }
    
    fn(function (str, n) {
    
    })
    
    const fo: 'foo' = 'foo'
    
    // 联合类型,变量的值只能是其中之一
    const type: 'success' | 'warning' | 'danger' = 'success'
    
    // 变量类型只能是其中的一种类型
    const g: string | number = 100
    
    type StringOrNumber = string | number
    const h: StringOrNumber = 'stri' // 100
    
    // maybe类型 加一个问号,变量除了可以接受number类型以外,还可以接受null或undefined
    const gender: ?number = null
    // 相当于
    // const gender: number | null | void = undefined
    
    // Mixed / Any  mixed是强类型,any是弱类型,为了兼容老代码,是不安全的,尽量不用any
    // string | number | boolean |...
    function passMixed (value: mixed) {
    
    }
    passMixed('string')
    passMixed(100)
    
    function passAny (value: any) {
    
    }
    passAny('string')
    passAny(100)
    
    const element: HTMLElement | null = document.getElementById('root')
    

    6.运行环境API

    三、TypeScript

    TypeScript:JavaScript超集/扩展集

    1.安装并使用typescript模块

    • yarn add typescript --dev
    • 创建一个扩展名为ts的文件,myTypeScript.ts:
    // TypeScript 可以完全按照JavaScript 标准语法编码
    const hello = (name: string) => {
      console.log(`hello, ${name}`)
    }
    
    hello('TypeScript')
    // hello(111)
    
    • 执行yarn tsc myTypeScript.ts,会生成一个同名的js文件
    • 查看myTypeScript.js
    // TypeScript 可以完全按照JavaScript 标准语法编码
    var hello = function (name) {
        console.log("hello, " + name);
    };
    hello('TypeScript');
    // hello(111)
    

    2.tsc命令的作用

    tsc:(typescript compiler) 编译ts文件: 执行命令yarn tsc myTypeScript.ts

    • 检查类型使用异常
    • 移除注解之类的扩展语法
    • 自动转换ECMAScript的新特性
      tsc编译整个项目:
    • 执行命令yarn tsc --init,生成tsconfig.json文件
    • 执行命令yarn tsc, 按照配置文件将src中的ts文件生成到了dist中的js文件,并且是采用ES2015语法

    3.TS支持的原始类型

    const a: string = 'foobar'
    
    const b: number = 100 // NaN Infinity
    
    const c: boolean = true // false
    
    // const d: boolean = null // 严格模式下不支持赋值null
    
    const e: void = undefined // 函数没有返回值时的返回值类型
    
    const f: null = null
    
    const g: undefined = undefined
    
    const h: symbol = Symbol()
    

    4.TS标准库声明

    标准库就是内置对象所对应的声明
    在tsconfig.json中写上:

    "lib": ["ES2015", "DOM"], 
    

    5.错误消息中文显示设置

    yarn tsc --locale zh-CN
    

    6.作用域

    每个文件都是全局作用域,所以在不同文件中定义同名变量会报错,解决方案:

    • 使用立即执行函数,产生作用域
    (function () {
      const a = 123
    } )()
    
    • 使用export
    const a = 11
    export {} // 确保跟其他实例没有成员冲突
    

    7.Object类型

    TypeScript中的Object类型泛指所有的的非原始类型。如对象、数组、函数.
    object类型并不单指对象,而是指除了原始类型之外的其他类型.
    对象的赋值必须与定义的属性保持一致,不能多也不能少。更专业的写法是用接口.

    export {} // 确保跟其他实例没有成员冲突
    
    const foo: object = function () {} // [] // {} 
    
    const obj: {foo: number, bar: string} = {foo: 123, bar: 'string'} 
    
    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)
    

    8.元组类型

    固定长度的数据。 例如Object.entries(obj)的返回值里面的每一个元素都是一个元组

    export {}
    
    const tuple: [number, string] = [19, 'jal']
    // 下标取值
    // const age = tuple[0]
    // const name = tuple[1]
    
    // 数组解构
    const [age, name] = tuple
    

    9.枚举类型

    // JS中没有枚举类型,则使用对象模拟枚举类型
    // const PostStatus = {
    //   Draft: 0,
    //   Uppublished: 1,
    //   Published: 2
    // }
    
    // 枚举类型。使用时和对象属性一样
    // 如果不指定值,则从0开始累加。如果制定了第一个成员的值,后面的成员则再第一个成员基础上累加。值如果是字符串,就得指定具体的值
    const enum PostStatus {
      Draft = 0, 
      Uppublished = 1,
      Published = 2
    }
    
    const post = {
      title: 'Hello TypeScript',
      content: 'Type...',
      status: PostStatus.Draft
    }
    

    10.函数类型

    // 获取不确定参数
    // function func1 (a: number, b: number): string {
    // function func1 (a: number, b?: number): string {
    // function func1 (a: number, b: number = 10): string {
    function func1 (a: number, b: number = 10, ...rest: number[]): string {
      return 'func1'
    }
    
    func1(100, 200)
    
    func1(100)
    
    func1(100, 200, 300)
    
    // 指定函数的形式
    const func2: (a: number, b: number) => string = function (a: number, b: number ): string {
      return 'f'
    }
    

    11.任意类型

    any类型是为了兼容老的代码,它还是动态类型,是不安全的,尽量少用

    function stringify (value: any) {
      return JSON.stringify(value)
    }
    
    stringify('string')
    stringify(100)
    stringify(true)
    
    let foo: any = 'string'
    foo = 100
    
    foo.bar()
    

    12.隐式类型推断

    let age = 18 // ts推断出类型是number
    // age = 'str' // 会报错 不能将类型“"str"”分配给类型“number”。
    
    let foo // 此时无法推断具体类型,foo则是动态类型,any类型
    foo = 1 // 不会报错
    foo = 'string' // 不会报错
    

    13.类型断言

    const nums = [110, 120, 119, 112]
    
    const res = nums.find(i => i>0)
    // const res: number | undefined
    // const square = res * res
    
    const num1 = res as number // 断言 res 是number
    const square = num1 * num1
    const num2 = <number>res // 或者这种方式。JSX下不能使用
    

    14.接口

    // 可以用分号分割,分号可以省略
    interface Post {
      title: String
      content: String
    }
    
    function printPost (post: Post) {
      console.log(post.title)
      console.log(post.content)
    }
    
    printPost({
      title: 'hello',
      content: 'javascript'
    })
    

    可选属性、只读属性

    interface Post {
      title: String
      content: String
      subtitle?: string // 可有可无的属性。也就是说该属性为string或者undefined
      readonly summary: string
    }
    
    const hello: Post = {
      title: 'hello',
      content: 'javascript',
      summary: 'js'
    }
    
    //报错: Cannot assign to 'summary' because it is a read-only property.
    // hello.summary = '11'
    

    动态属性

    interface Cache {
      // 动态成员
      [prop: string]: string
    }
    
    const cache: Cache = {}
    
    cache.foo = 'ff'
    

    15.类

    TypeScript增强了class的相关语法

    • 类的基本使用
    class Person {
      // ES2017定义的语法:
      name: string // = 'init name'
      age: number
      constructor(name: string, age: number) {
        this.name = name
        this.age = age
      }
      sayHi (msg: string): void {
        console.log(`I am ${this.name}`)
      }
    }
    
    • 访问修饰符:private public protected 。默认是public.
    export {}
    
    class Person {
      // ES2017定义的语法:
      name: string // = 'init name'
      private age: number
      protected gender: boolean
      constructor(name: string, age: number) {
        this.name = name
        this.age = age
        this.gender = true
      }
      sayHi (msg: string): void {
        console.log(`I am ${this.name}`)
      }
    }
    
    const tom = new Person('tom', 18)
    console.log(tom.name)
    // console.log(tom.age) // 属性“age”为私有属性,只能在类“Person”中访问。
    // console.log(tom.gender) // 属性“gender”受保护,只能在类“Person”及其子类中访问。
    
    class Student extends Person {
      constructor(name: string, age: number) {
        super(name, age)
        // 父类的protected属性子类可以访问。
        console.log(this.gender)
      }
    }
    
    • 静态属性、构造器私有化后不能new
    class Student extends Person {
      private constructor(name: string, age: number) {
        super(name, age)
        console.log(this.gender)
      }
      static create(name: string, age: number) {
        return new Student(name, age)
      }
    }
    
    const jack = Student.create('jack', 18)
    
    • 只读属性,在属性声明前面加上readonly即可
    protected readonly gender: boolean
    

    16.类与接口

    // 尽可能让接口简单。一个接口只约束一个能力,一个类实现多个接口
    interface Eat {
      eat (foo: string): void
    }
    interface Run {
      run (distance: number): void
    }
    class  Person implements Eat, Run {
      eat(food: string): void {
        console.log(`优雅的进餐:${food}`)
      }
      run(distance: number): void {
        console.log(`直立行走:${distance}`)
      }
    }
    
    class  Animal implements Eat, Run {
      eat(food: string): void {
        console.log(`呼噜呼噜的吃:${food}`)
      }
      run(distance: number): void {
        console.log(`爬行:${distance}`)
      }
    }
    

    17.抽象类

    被abstract修饰,不能被new,只能被继承。继承抽象类的子类,必须实现父类的抽象方法

    abstract class Animal {
      eat (food: string) : void {
        console.log(`呼噜呼噜的吃:${food}`)
      }
    
      // 抽象方法不需要方法体,子类必须要实现抽象方法
      abstract run(distance: number): void
    }
    
    // 非抽象类“Dog”不会实现继承自“Animal”类的抽象成员“run”
    class Dog extends Animal {
      run(distance: number): void {
        console.log(`四脚爬行:${distance}`)
      }
    }
    
    const dog = new Dog()
    dog.run(20)
    dog.eat('fish')
    

    18. 泛型

    把类型作为参数,放在尖括号中

    function createNumberArray(length: number, value: number): number[] {
      const arr = Array<number>(length).fill(value)
      return arr
    }
    
    const res = createNumberArray(3, 100 ) // [100, 100, 100]
    
    function createArray<T> (length: Number, value: T): T[] {
      const arr = Array<T>(length).fill(value)
    }
    
    const arrRes = createArray<string>(3, 'foo') // ['foo', 'foo', 'foo']
    

    19. 类型声明

    TypeScript中的扩展名为d.ts的文件就是类型声明文件

    import {camelCase} from 'lodash'
    
    // 自己写declare语句声明类型
    declare function camelCase (input: string): string
    
    const res = camelCase('zjal')
    

    相关文章

      网友评论

          本文标题:笔记四:TypeScript语言

          本文链接:https://www.haomeiwen.com/subject/kabxrktx.html