Skip to content

TypeScript(基本类型和接口) #53

@huangchucai

Description

@huangchucai

TypeScript

基础类型

  1. Number

    const age: number = 25
  2. String

    const name: string = 'hcc'
  3. Boolean

    const isDone: boolean = false
  4. Array (number[])

    const arr: number[] = [1,2,3]
    const arr: Array<number> = [1,2,3]
    const arr: any[] = ['name', 25];
  5. Tuple(元组,和数组使用)

    • 元组类型允许表示一个已知元素数量和类型数组,各元素的类型不必相同
    // 申明的时候
    const tuple1: [string, number] = ['hcc',26]
    • 当值超过了元组的边界的时候,会使用联合类型进行判定
    tuple1[3] = 'vip'
    tuple1[6] = false // error
  6. Enum(枚举, 对象的形式) (通常运用于状态统计)

    • enum类型是对JavaScript标准数据类型的一个补充,使用枚举类型可以为一组数值赋予友好的名字
    • 可以通过成员的数值获取成员的属性,也可以通过属性获取数值
    enum Color {Red=1, Green, Blue}
    let c: Color = Color.Blue // 3
    let d: string = Color[2] // Green
  7. Any(任意数据类型)

    const list: any[] = [1, 'hcc', true];
    const age: any = 'hcc'
  8. Void(没有数据类型)

    • 一般当函数没有返回值的时候,通常就会使用void
    function test(name: string): void{
        console.log(`This is a ${name}`)
    }
  9. Null 和 Undefined

    • 表示Null和Undefined二种类型
    • 在非strictNullChecks下,Null和Undefined是任意类型的子类型,当指定了--strictNullChecks标记的时候,nullundefined只能赋值给void和它们各自。
    const u: undefined = undefined;
    const n: null = null
    // 子类型
    const age: number = null;
    const name: string = undefined;
  10. Never(一般用于抛出错误)

    function sendNever(): never {
        throw new Error('出错了')
    }
  11. Type assertions (someValue 断言)

    const name: string = 'hcc';
    // 第一种语法
    const length: number = (<string>name).length 
    // 第二种语法 jsx只支持这种语法
    const length: number = (name as string).length

变量申明

  1. let 、const
  2. 解构

接口(主要用来定义对象的类型)

  1. 只要相应的属性存在且类型也存在的就可以通过
    interface LabelledValue{
        label: string;
        name: string
    }
    function interfaceTest1(labelObject: LabelledValue): void {
        console.log(labelObject.label)
    }
  2. 接口的可选属性(key?: type)
    interface SquareConfig {
        color?: string;
        width?: number;
    }
    function createSquare(config: SquareConfig):void {
        if (config.width) {
            console.log('存在width');
        } else if (config.color) { 
            console.log('存在color')
        }
    }
  3. 只读属性(readonly x: type)
    • 只读属性
    interface ReadonlyPerproty {
        readonly name: string;
        age: number
    }
    const obj: ReadonlyPerproty = {
        name: 'hcc',
        age: 26
    }
    obj.name = 'yx' // error name是只读属性和常数
    obj.age = 24 
    • 数组只读(ReadonlyArray)

      把数组的所有的方法去掉了,确保创建后再也不能被修改,只能读取,不能设置

    const a: number[] = [1, 2, 3, 4];
    
    const arrReadonly: ReadonlyArray<number> = a;
    
    console.log(arrReadonly[2]); // 3
    arrReadonly[2] = 3; // error 仅允许读取
    arrReadonly.push(5) // error 不存在push
    • readonly vs const

    它们2个都作为一个常量的使用,一般我们在使用变量的时候就用const, 在作为属性的时候使用readonly

  4. 额外的属性检查

    对象字面量在ts中会被特殊对待,并进行额外的属性检查,当它们被赋值给一个变量或者函数的参数的时候,如果里面存在任何“目标类型(接口)”不包括的属性的话,ts就会报错。

    interface SquareConfig {
      width?: number;
      color?: string;
    }
    // 作为变量
    const obj: SquareConfig = {
        width: 60,
        color: 'white',
        coloru: 'fff' //error 对象文字只能指定已知的属性,但“coloru”中不存在类型“SquareConfig”。是否要写入 color?
    }
    // 作为函数参数
    function createSquare(config: SquareConfig) {
        //...
    }
    createSquare({ colour: 'red', width: 50 }) // error

    我们的项目中不可能一开始就定义号所有的属性,假如:我们就需要额外的参数作为变量和参数,我们应该怎么办呢?

    • 解决方法
    1. 我们可以使用断言的方法绕过检查

      // 作为变量
      const obj: SquareConfig = {
          width: 60;
          color: 'white',
          coloru: 'fff'
      } as SquareConfig
      // 作为函数参数
      createSquare({ colour: 'red', width: 50 } as SquareConfig)
    2. 使用索引签名([propName: string]: any)改变定义的接口 (最长使用第6小点)

      // 改变接口的定义
      interface SquareConfig {
        width?: number;
        color?: string;
        [propName: string]: any;
      }
      // [propName: string]: any;  必须包含已经定义的类型(number|string / any)
    3. 赋值给另一个变量,绕过检查 (尽量不用)

      let squareOptions = { colour: "red", width: 100 };
      let mySquare = createSquare(squareOptions);
  5. 函数类型

    我们知道函数主要的是参数和返回值,所以ts中,接口可以让我们定义函数的参数和返回值,但是函数的参数名不需要和规定的一样,只要类型一直就可以

    interface SearchFunc {
      (source: string, subString: string): boolean;
    }
    // 参数名可以不一样,但是类型必须一样
    let mySearch: SearchFunc = (src: string, sub: string) => {
      return false;
    };
  6. 可索引的类型 (不常用)
    1. ts只支持2种索引签名: 字符串和数字
    2. 数字的类型必须是字符串的子类型
    3. 索引签名也可以设置为只读,这样就不能赋值了
    4. 同索引类型,值类型必须一致
    // age是字符串类型,索引值也必须是string,而不能是number
    interface objDictionary {
        [propName: string]: string;
        age: number; // error
    }
    interface objDictionart {
        [propName: number]: string;
        age: number // 正确 可索引的类型是number,而age类型是string,不受限制
    }
    
    // 数组
    interface arrRule {
      readonly [index: number]: number
    }
    let myArray: arrRule = [1,3,4]
    myArray[2] = 10; //error  索引签名仅允许读取
  7. 类类型接口(常用: 对类的约束 implemets)
    1. implements是对类的约束,而不是对实例的约束
    2. 当一个类实现(implements)一个接口时,只会对其实例部分进行检测,而constructor存在类的静态方法,不会被检查
    3. 在类中,引用任何一个类成员的时候都用了 this。 它表示我们访问的是类的成员,当使用new 执行类的时候,this返回实例
    // 接口定义了需要有name属性和setAge方法
    interface Animal {
      name: string;
      setAge(age: number): void;
    }
    // 类中有name属性和setAge方法,ts并没有检查constructor中的参数值
    class Dog implements Animal {
      name: string
      setAge(age: number) {
        console.log(`${this.name}今年${age}岁`)
      }
      constructor(name:string) {
        this.name = name
      }
    }
    
    const dog = new Dog('bh')
    dog.setAge(24)
  8. 接口继承(extends)
    • 接口继承接口:和类一样,接口也是可以继承使用的,这样我们可以把一个接口里面的成员复制到另一个接口中,方便我们灵活的复用
    interface Animal {
      species: string
    }
    interface Color {
      color: string
    }
    // 继承一个接口
    interface Cat extends Animal {
      foot: string
      age: number
    }
    // 继承多个接口
    interface Dog extends Animal,Color {
        size: string
    }
    const cat: Cat = <Cat>{}
    cat.species = "猫科"
    cat.foot = '只'
    cat.age = 24
    • 接口继承类:当接口继承一个类的时候,就会继承类的private和protected成员,这意味着当你创建了一个接口继承了一个拥有私有或受保护的成员的类时,这个接口类型只能被这个类或其子类所实现(implement),公有属性则不用。
    class Animal {
      private species: string;
    }
    // 继承一个类
    interface Cat extends Animal {
      age: number;
    }
    // error 因为属性“species”在类型“Cat”中是私有属性
    class BlueCat implements Cat {
      age: 23;
      species: 'ff'
    }
    // 正确
    class BlueCat extends Animal implements Cat {
      age: 23;
    }
  9. 混合类型

    接口描述javaScript提供丰富的类型,因为有时候一个对象拥有多种类型

    interface Counter {
      (start: number): string
      interval: number;
      reset(): void
    }
    function getCounter(): Counter {
      const counter = <Counter>function(start: number) { }
      counter.interval = 4;
      counter.reset = () => { }
      return counter
    }
    const c = getCounter()
    c(10)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions