TS中type和interface在类型声明时的区别

在TS中interfacetype都可以用来自定义数据类型,两者有许多相同之处,但是也有差别。我们一般选择 type 来定义基本类型别名、联合类型、元组等类型,而选择 interface 来定义复杂的对象、类、以及进行接口的继承。

1. 声明常见类型 和 方法

        TS中常用的基本类型可以细分为两类:1. js已有类型,2.ts新增类型。

  • JS 已有类型(原始类型):
原始类型例子描述
number1,-22,1.3任意数字
string“af”,“JF”任意字符串
booleantrue, false布尔值
nullnull空值
undefinedundefined未定义
symbolsymbolsymbol
let a: number = 18;
let b: string = '字符串';
let c: boolean = true;
let d: null = null;
let e: undefined = undefined;
let f: symbol = Symbol();
  • JS 已有类型(对象类型):
对象类型例子描述
object{age: 45}任意的js对象
array[1,2,3]任意的js数组
function(a,b)=>a+b函数类型

TS 新增类型:

类型描述
字面量限制变量的值就是该字面量的值
any任意类型
unknown类型安全的any
void没有值
never不能是任何值
tuple元组,固定长度数组
enum枚举
type类型别名
interface接口

interface 可以表示对象的各种语法,它的成员有5种形式。

  • 对象属性
  • 对象的属性索引
  • 对象方法
  • 函数
  • 构造函数

对象的方法:

interface对象的方法共有三种写法。

第一种:参数后接冒号+类型,返回值类型在参数列表圆括号外

第二种:箭头函数形式

第三种:圆括号定义参数类型,参数外定义返回值类型

// 写法一
interface A {
  f(x: boolean): string;
}

// 写法二
interface B {
  f: (x: boolean) => string;
}

// 写法三
interface C {
  f: { (x: boolean): string };
}

type对象的方法写法。

type A = (name: string) => string;


export type A = {
   (name: string): string;
}

对象的方法:可以用来声明独立的函数

interface Add {
  (x:number, y:number): number;
}

const myAdd:Add = (x,y) => x + y;

 构造函数 interface内部使用new关键字,表示构造函数

interface ErrorConstructor {
  new (message?: string): Error;
}

(1)定义基本类型

type Age = number;

interface Person {
  name: string;
  age: Age;
}

(2)定义函数类型

type Greeting = (name: string) => string;

type Greetingnum = {
   (name: string): string;
}

interface Greeter {
  (name: string): string;
}

(3)定义对象类型

type Point = { x: number; y: number };

interface Rectangle {
  width: number;
  height: number;
  position: Point;
}

(4)定义泛型

T 是泛型变量,表示任何类型

type List<T> = {
  data: T[];
  add: (item: T) => void;
}

interface List<T> {
  data: T[];
  add: (item: T) => void;
}

1.interface使用泛型的案例如下:

interface Container<T> {
  value: T;
  get(): T;
  set(value: T): void;
}

class NumberContainer implements Container<number> {
  value: number;
  get() {
    return this.value;
  }
  set(value: number) {
    this.value = value;
  }
}

const container = new NumberContainer();
container.set(42);
console.log(container.get()); // 

2. interface 可以被类(class)实现(implement),而 type 不能

interface Animal {
  name: string;
  speak: () => void;
}

class Dog implements Animal {
  name: string;
  constructor(name: string) {
    this.name = name;
  }
  speak() {
    console.log("hello!");
  }
}
const myDog = new Dog("Sparky");
myDog.speak(); // 输出 hello

6.interface 可以定义多个同名接口并合并,而 type 不支持

interface User {
  name: string;
  age: number;
}

interface User {
  gender: 'male' | 'female';
}

const user: User = {
  name: '猫先生',
  age: 25,
  gender: 'male',
};

7.type可以使用 typeof 获取实例的类型,而 interface 不支持

type Person = {
  name: string;
  age: number;
}

const john: Person = {
  name: "John",
  age: 30,
}

type PersonType = typeof john; // 类型为 { name: string, age: number }

8、索引签名类型([key: type]: type

  • 使得对象中可以出现任意多个属性
// [propName: string]: any 表示任意类型的属性
let h: {name: string, [propName: string]: any};
h  = {name: "张三", age: 13, gender: "男"};


/*
	1.  使用[key: string]来约束该接口中允许出现的属性名称。
	2. 表示只要是string类型的属性名称,都可以出现在对象中。
	3. 这样,对象 obj 中就可以出现任意多个属性
	4. key 只是一个占位符,可以换成任意合法的变量名称。
	5. 须知:js中对象的键是 string 类型的。
*/
interface AnyObject {
	[key: string]: number;
}
let obj: AnyObject = {
	a: 1,
	b: 2,
}

 2.interface继承

 1. interface 支持 extends 实现接口的继承,而 type 不支持

      (1)单接口继承
interface Animal {
	name: string;
	speak: () => void;
  }
  
interface Pet extends Animal {
	owner: string;
	play: () => void;
  }
  
class Dog implements Pet {
	name: string;
	owner: string;
	constructor(name: string, owner: string) {
	  this.name = name;
	  this.owner = owner;
	}
	speak() {
	  console.log("speak:hello");
	}
	play() {
	  console.log(`${this.name} is playing with ${this.owner}`);
	}
  }
  
  const myDog = new Dog("myPet", "Mr.Cat");
  myDog.speak(); // 输出 "speak:hello" 
  myDog.play(); // 输出 "myPet is playing with Mr.Cat" 
                (2)多接口继承

1、type 只是类型别名,不能包含具体的属性和方法实现,因此它不支持通过 extends 关键字实现接口的继承。如果需要继承类型别名,需要使用交叉类型进行组合。

2、当你需要让一个接口继承多个其他接口时,使用 interface 更加方便。因为 interface 允许你使用逗号分隔的方式来继承多个接口,而 type 只能使用交叉类型(&)来实现继承。

interface Person {
  name: string;
  age: number;
}

interface Employee {
  company: string;
  jobTitle: string;
}

interface Manager extends Person, Employee {
  teamSize: number;
}

const manager: Manager = {
  name: 'John Doe',
  age: 40,
  company: 'ABC Inc.',
  jobTitle: 'Manager',
  teamSize: 10,
};




interface Person {name: string};
interface Contact {phone: string};
type PersonDetail = Person & Contact
let obj: PersonDetail = {
	name: 'jack',
	phone: '15698324'
}
// 使用交叉类型后,新的类型PersonDetail就同时具备了Person和Contact的所有属性类型。
// 相当于:
type PersonDetail = {name: string; phone: string;}
3、interface继承type 

可以继承type命令定义的对象类型,如果其他类型则无法继承。

type Country = {
  name: string;
  capital: string;
}

interface CountryWithPop extends Country {
  population: number;
}
4、interface 继承class
class A {
  x:string = '';

  y():boolean {
    return true;
  }
}

interface B extends A {
  z: number
}

 3.type继承

 1、type 也可以继承 interface。
interface Foo {
  x: number;
}

type Bar = Foo & { y: number; };

继承时,type 和 interface 是可以换用的。interface 可以继承 type。

type Foo = { x: number; };

interface Bar extends Foo {
  y: number;
}

2.接口继承 type之间的继承
//&连接 两个必须都满足
type Person = {
  age: string
}
 
type People1 = {
  name: string
} & Person



 
 
 |只能满足一个,两个不能同时满足
type People2 =
  | {
      name: string
    }
  | Person




4.class

1、封装
class Animal{
    constructor(name){ //接收参数
        this.name = name
    }
    run(){
        console.log( this.name+'可以跑起来!')
    }
}
 
console.log(111);
const dog = new Animal('小黑')
dog.run()
2、继承

1、使用extends关键字实现继承

2、子类可以继承父类中所有的方法和属性

3、子类只能继承一个父类(单继承),一个父类可以有多个子类

4、子类的构造方法中必须有super()来指定调用父类的构造方法,并且位于子类构造方法中的第一行

5、子类中如果有与父类相同的方法和属性,将会优先使用子类的(覆盖)

class Dog extends Animal{
    bark(){
        return `${this.name} 是一只狗`
    }
}
console.log(222);
const mazi = new Dog('校长')
mazi.run()
console.log(mazi.bark)
3.多态
class JinMao extends Dog{
    static categories = ['manmal']  //static-修饰符,静态属性
 
    constructor(name){                    
        super(name)  //子类构造函数中必须用super()
        consoe.log(this.name)
    }
 
    run(){
        return 'memow'+super.run()  //调用父类的run函数
    }
} 
 
console.log(333);
const maomao = new JinMao('maomao')
maomao.run()
 
//static 定义的变量和方法,可以直接用  方法名+点+变量/方法名()   调用
console.log(  JinMao.categories  );
一、ts新增的 class的方法


ts中的class又增加了三种修饰符,用来给类中的属性与方法设置权限,更易管理。

public:修饰的属性与方法是共有的,默认;
private:修饰的属性和方法是私有的,只能在class里使用,通过该类new出来的实例、继承的子类也不能使用;
protected:修饰的属性与方法是受保护的,继承的子类可以使用。

1、public
class Animal {
  public name;
  public constructor(name) {
    this.name = name;
  }
}
 
let a = new Animal('Jack');
console.log(a.name); // Jack
a.name = 'Tom';
console.log(a.name); // Tom
2、private
class Animal{
    private run(){
        return `${this.name} is running`
    }
}
 
const snake = new Animal()
console.log(snake.run())            //报错,run已变成私有方法,不能被使用
3、protected   继承的子类可以使用
class Animal {
  protected name;
}
 
class Cat extends Animal {
  constructor(name) {
    super(name);
    console.log(this.name);
  }
}
4、readonly 只读属性

注意如果 readonly 和其他修饰符同时存在的话,需要写在其后面。

class Animal {
  readonly name;
}
 
let a = new Animal();
console.log(a.name); // Jack
a.name = 'Tom';   //无法修改

5. interface可以扩展,type可以通过交叉实现interface的extends行为,interface可以extends type,同时type也可以与interface类型交叉 。 

// interface通过extends实现继承
interface userName {
  name: string;
}
interface user extends userName {
  age: number
}
let stu:user = {name: 'wang', age: 10}
 
// interface的extends扩展可以通过type交叉(&)类型实现
type userName = {
   name: string;
}
type user = userName & {age: number}
let stu:user={name: 'wang', age: 18}
 
// interface扩展type
type name = {
  name: string;
}
interface user extends name {
  age: number;
}
let stu:user={name: 'wang', age: 89}
 
// type与interface交叉
interface name {
  name: string;
}
type user = name & {
  age: number;
}
let stu:user={name:'wang', age: 18}

6.混合类型的 Interface

混合类型的接口就是使用同一个 Interface 来描述函数或者对象的属性或方法。

// 混合类型接口
interface MixType {
      // 如果只有这么一个,那么这个接口是函数接口
      (x: number, y: number): number,
      // 还含有其他方法,那么这个接口就是混合接口
      add(x: number, y: number): number,
      // 还有另一个方法
      log(): void,
      (): void
}
// 调用
function sum() {
      let sum: MixType = (() => { }) as MixType;
      sum.add = (x: number, y: number) => { return x + y }
      sum.log = () => { }
}
 
const isShowModal = ref(false)
function open() {
      isShowModal.value = true
}

7.ts里面的  type  和  interface  的区别

        1、区别

相同:

        都可以用来定义 对象 或者 函数 的结构,而严谨的来说,type 是引用,而 interface是定义

不同:

1、type (alias)类型别名,可以定义基础类型、联合类型或交叉类型。interface 接口,只能定义对象,

2、接口可以 extends、implements,从而扩展多个接口或类。 type没有扩展功能,只能交叉合并

3、定义两个相同名称的接口会合并声明,定义两个同名的 type 会出现异常。

4、type 在声明类型别名之后实际上是一个赋值操作,它需要将别名与类型关联起来。也就是说类型别名不会创建出一种新的类型,它只是给已有类型命名并直接进行引用。interface是定义了一个接口类型

  • 22
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
TypeScript,可以使用interface关键字来定义接口,并且可以通过export关键字将接口导出。导出接口的方式有两种,一种是直接在定义接口的同使用export关键字导出,例如: export interface Config { name: string; } 另一种方式是先定义接口,然后在另一个文件使用export default关键字导出接口,例如: interface Config { name: string; } export default Config; 这样就可以在其他文件使用import语句导入并使用该接口了。需要注意的是,interface支持同声明和默认导出,而type不支持。 值得一提的是,interfacetype alias在继承方式上也有区别interface使用extends关键字来进行扩展,例如: interface Animal { name: string; } interface Bear extends Animal { honey: boolean; } 而type alias使用&操作符来进行扩展,例如: type Animal = { name: string; } type Bear = Animal & { honey: boolean; } 这就是在TypeScript使用interface导出的方式。希望能对你有所帮助!<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [TSinterfacetype区别](https://blog.csdn.net/yhl521112/article/details/124836325)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [ts -type alias 和interface区别](https://blog.csdn.net/weixin_28750673/article/details/124841143)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [json-to-ts-interface:json字符串自动转换为TypeScript interface定义](https://download.csdn.net/download/weixin_42116701/19195334)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

记忆深处里的海

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值