ts的理解,type和interface区别,泛型怎么理解

TypeScript (TS) 的理解

  1. TypeScript (TS) 的理解:
    TypeScript 是 JavaScript 的一个超集,为 JavaScript 增加了静态类型、类、接口等特性。其主要目的是增强代码的可读性和可维护性,同时捕获开发过程中可能出现的错误。

type和interface区别:

在大多数情况下,interfacetype 是可以互换使用的:

  • 相似点:

    • 两者都可以描述一个对象或函数的形状。
  • 主要区别:

    • 声明合并interface 在定义时可以合并多次。如果两个 interface 有相同的名字,它们会被自动合并成一个。但是,当您使用 type 时,您不能有两个相同名称的 type
    • 使用联合 (Union) 和交叉 (Intersection) 类型type 有更大的灵活性,可以使用联合和交叉类型,而 interface 不可以。
    • implements与extends:类可以实现 (implements) interface,但不能实现 (implements) type。类可以继承 (extends) type 如果 type 描述了类的形状。
    • 计算属性type 可以使用计算属性,interface 不可以。

总体来说,在大多数情况下,interfacetype 可以互换使用,但是在一些特殊情况下,它们具有一些细微的差异,需要根据具体情况来选择使用哪个。一般来说,如果需要声明合并、实现接口、继承类等高级类型定义,优先选择使用 interface。而对于复杂的类型操作,比如联合类型、交叉类型、泛型类型等,type 可能更为灵活和方便。

泛型的理解:

泛型是在定义函数、接口或类时,不预先确定方法的具体类型,而是在使用时才决定的一种特性。使用泛型可以创建可重用的组件,组件不仅能够支持当前的数据类型,还能支持未来的数据类型,给予用户更大的灵活性。例如:

function identity<T>(arg: T): T {
    return arg;
}

在上面的例子中,T 是一个类型变量,它帮助我们捕获用户提供的类型,例如:numberstring,但不限于这些两种。

联合 (Union) 和交叉 (Intersection) 类型是什么?请举例

在 TypeScript 中,联合(Union)和交叉(Intersection)类型是两种用于组合多种类型的强大工具。

  1. 联合类型 (Union Types):
    联合类型使用 | 符号来表示一个值可以是多种类型之一

    举例:

    type StringOrNumber = string | number;
    
    let myVar: StringOrNumber;
    
    myVar = 'Hello';  // 有效,因为 'Hello' 是一个 string 类型
    myVar = 123;      // 有效,因为 123 是一个 number 类型
    

    使用联合类型时,你只能访问此联合类型的所有类型里共有的成员。

  2. 交叉类型 (Intersection Types):
    交叉类型使用 & 符号来组合多个类型,让你可以将多个类型合并为一个类型

    举例:

    interface Name {
        name: string;
    }
    
    interface Age {
        age: number;
    }
    
    type Person = Name & Age;
    
    let person: Person = {
        name: 'Alice',
        age: 30
    };
    

    使用交叉类型,person 变量必须具有 NameAge 接口中定义的所有属性。

希望这些示例可以帮助您更好地理解联合类型和交叉类型!

implements与extends

类可以实现 (implements) interface,但不能实现 (implements) type。类可以继承 (extends) type 如果 type 描述了类的形状。

  1. 类实现 (implements) interface:

    interface Movable {
        move(distance: number): void;
    }
    
    class Car implements Movable {
        move(distance: number) {
            console.log(`Car moved ${distance} meters.`);
        }
    }
    
  2. 类不能实现 (implements) type,但可以继承 (extends) type:

    这个要分两个例子来说明:

    • 不能实现一个 type:

      type MovableType = {
          move(distance: number): void;
      };
      
      // 这里会产生错误,因为类不能实现一个 type
      class Car implements MovableType {
          move(distance: number) {
              console.log(`Car moved ${distance} meters.`);
          }
      }
      
    • 但如果 type 描述了类的形状,类可以继承它:

      type Vehicle = {
          new (name: string): Vehicle;
          name: string;
          drive(): void;
      };
      
      class Car extends (class implements Vehicle {
          name: string;
          constructor(name: string) {
              this.name = name;
          }
          drive() {
              console.log(`${this.name} drives.`);
          }
      }) {}
      

这里的关键在于,type 是一个值的类型别名,而不是一个真正的类型。当 type 描述一个具有构造签名的类型时(如上面的 Vehicle 示例),它事实上是描述了一个类的形状,这时它可以被一个类继承。但在通常情况下,类不能直接实现 type

计算属性

当谈到 TypeScript 的计算属性,我们通常指的是对象字面量中的计算属性键。与 ES6 中的对象字面量计算属性类似,TypeScript 也允许你使用表达式来定义类型的属性键。

  1. 使用 type 定义计算属性:

    const propName = "name";
    
    type MyType = {
        [propName]: string;  // 使用计算属性
        age: number;
    };
    
    let obj: MyType = {
        name: 'Alice',
        age: 30
    };
    
  2. 使用 interface 时无法直接定义计算属性:

    以下是错误的示例:

    const propName = "name";
    
    interface MyInterface {
        [propName]: string;  // 这里会产生错误
        age: number;
    }
    

    然而,需要注意的是,尽管 interface 不能直接定义计算属性,但它们可以定义索引签名来表示某些类型的属性集合,这是一个稍微不同的概念。

总的来说,如果你需要在类型中使用基于某种计算或常量的属性名称,type 会是更合适的选择。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值