javascript技巧

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript技巧 > TS type和interface区别

TypeScript中type和interface的区别示例详解

作者:山高自有客行路

在TypeScript中interface和class都是用来定义类型的工具,但它们有不同的用途和功能,这篇文章主要介绍了TypeScript中type和interface区别的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下

1. 扩展方式

Interface

接口支持通过 extends 关键字进行扩展,并且可以继承多个接口。

// 定义基础接口
interface Animal {
  name: string;
}

// 扩展接口并添加更多属性
interface Bear extends Animal {
  honey: boolean;
}

const myBear: Bear = { name: "Yogi", honey: true };
console.log(myBear); // 输出: { name: 'Yogi', honey: true }

// 多重继承
interface FlyingAnimal extends Animal {
  canFly: boolean;
}

interface Eagle extends Animal, FlyingAnimal {
  talons: number;
}

const myEagle: Eagle = { name: "Sam", canFly: true, talons: 2 };
console.log(myEagle); // 输出: { name: 'Sam', canFly: true, talons: 2 }

// 接口还可以包含方法
interface Bird extends Animal {
  fly(): void;
}

class Sparrow implements Bird {
  constructor(public name: string) {}

  fly() {
    console.log(`${this.name} is flying`);
  }
}

const sparrow = new Sparrow('Chirpy');
sparrow.fly(); // 输出: Chirpy is flying

Type

类型别名使用交叉类型(&)来实现类似的功能。

// 定义基础类型
type Animal = {
  name: string;
};

// 使用 & 来组合类型
type Bear = Animal & {
  honey: boolean;
};

const myBear: Bear = { name: "Yogi", honey: true };
console.log(myBear); // 输出: { name: 'Yogi', honey: true }

// 多重组合
type FlyingAnimal = Animal & {
  canFly: boolean;
};

type Eagle = Animal & FlyingAnimal & {
  talons: number;
};

const myEagle: Eagle = { name: "Sam", canFly: true, talons: 2 };
console.log(myEagle); // 输出: { name: 'Sam', canFly: true, talons: 2 }

// 类型别名也可以包含函数签名
type Bird = Animal & {
  fly: () => void;
};

const parrot: Bird = {
  name: "Polly",
  fly() {
    console.log(`${this.name} is flying`);
  }
};

parrot.fly(); // 输出: Polly is flying

2. 合并性

Interface

接口支持声明合并,这意味着相同的接口可以在不同的地方定义多次,TypeScript 会自动合并这些定义。

// 第一次定义
interface Box {
  height: number;
}

// 第二次定义,自动合并
interface Box {
  width: number;
}

const box: Box = { height: 10, width: 20 };
console.log(box); // 输出: { height: 10, width: 20 }

// 声明合并示例:添加方法
interface Box {
  getVolume(): number;
}

const boxWithMethod: Box = {
  height: 10,
  width: 20,
  getVolume() {
    return this.height * this.width;
  }
};
console.log(boxWithMethod.getVolume()); // 输出: 200

// 声明合并示例:添加静态成员
interface Box {
  new (height: number, width: number): Box;
}

class BoxClass implements Box {
  constructor(public height: number, public width: number) {}

  getVolume() {
    return this.height * this.width;
  }
}

const boxInstance = new BoxClass(10, 20);
console.log(boxInstance.getVolume()); // 输出: 200

Type

类型别名不支持这种声明合并。

type Box = {
  height: number;
};

// 下面的定义会导致编译错误
// type Box = {
//   width: number;
// };

// 类型别名不能合并方法
type BoxWithMethod = {
  height: number;
  getVolume(): number;
};

const boxWithMethod: BoxWithMethod = {
  height: 10,
  getVolume() {
    return this.height; // 注意这里没有宽度
  }
};
console.log(boxWithMethod.getVolume()); // 输出: 10

3. 描述非对象类型的能力

Interface

接口主要用于描述对象的形状或结构。

interface Point {
  x: number;
  y: number;
}

const point: Point = { x: 10, y: 20 };
console.log(point); // 输出: { x: 10, y: 20 }

Type

类型别名可以用来描述几乎所有类型的结构,包括联合类型、元组、基本数据类型等。

// 联合类型
type ID = string | number;

// 元组
type Coordinates = [number, number];

// 字符串字面量类型
type Direction = 'North' | 'South' | 'East' | 'West';

// 函数签名
type GreetFunction = (name: string) => string;

// 实例化
let id: ID = 123;
let coords: Coordinates = [10, 20];
let direction: Direction = 'North';
let greet: GreetFunction = (name: string) => `Hello, ${name}`;

console.log(id);       // 输出: 123
console.log(coords);   // 输出: [10, 20]
console.log(direction); // 输出: North
console.log(greet('Alice')); // 输出: Hello, Alice

// 更复杂的类型操作
type StringOrNumber = string | number;
type ArrayOfStringsOrNumbers = StringOrNumber[];
const mixedArray: ArrayOfStringsOrNumbers = ['hello', 42];
console.log(mixedArray); // 输出: ['hello', 42]

// 映射类型
type Keys = 'firstName' | 'lastName';
type PersonPartial<T> = {
  [P in Keys]?: T;
};

const partialPerson: PersonPartial<string> = { firstName: 'John' };
console.log(partialPerson); // 输出: { firstName: 'John' }

4. 实现

Interface

类可以直接实现接口,这意味着你必须实现接口中定义的所有成员。

interface HasName {
  name: string;
}

class Person implements HasName {
  constructor(public name: string) {}
}

const person = new Person('Alice');
console.log(person.name); // 输出: Alice

// 接口还可以包含方法
interface HasGreeting {
  greet(): string;
}

class Greeter implements HasGreeting {
  constructor(private message: string) {}

  greet(): string {
    return this.message;
  }
}

const greeter = new Greeter('Hello, world!');
console.log(greeter.greet()); // 输出: Hello, world!

Type

类型别名不能被类实现或继承。如果尝试这样做,TypeScript 会报错。

type HasName = {
  name: string;
};

// 下面的代码会导致编译错误
// class Person implements HasName {
//   constructor(public name: string) {}
// }

// 类型别名可以用于类型注解
const hasName: HasName = { name: 'Alice' };
console.log(hasName.name); // 输出: Alice

5. 泛型

Interface

interface Container<T> {
  value: T;
}

const container: Container<string> = { value: "Hello" };
console.log(container.value); // 输出: Hello

// 泛型接口与泛型类结合使用
class GenericContainer<T> implements Container<T> {
  constructor(public value: T) {}
}

const genericContainer = new GenericContainer("World");
console.log(genericContainer.value); // 输出: World

Type

type Container<T> = {
  value: T;
};

const container: Container<string> = { value: "Hello" };
console.log(container.value); // 输出: Hello

// 泛型类型别名与泛型类结合使用
class GenericContainer<T> implements Container<T> {
  constructor(public value: T) {}
}

const genericContainer = new GenericContainer("World");
console.log(genericContainer.value); // 输出: World

6. 混合类型

Interface

interface Counter {
  (start: number): string;
  interval: number;
  reset(): void;
}

function getCounter(): Counter {
  const counter = <Counter>function (start: number) {};
  counter.interval = 123;
  counter.reset = function () {};
  return counter;
}

const c = getCounter();
c(10);
c.reset();
c.interval = 5.0;

Type

type Counter = {
  (start: number): string;
  interval: number;
  reset(): void;
};

function getCounter(): Counter {
  const counter: Counter = function (start: number) { return ''; } as Counter;
  counter.interval = 123;
  counter.reset = function () {};
  return counter;
}

const c = getCounter();
c(10);
c.reset();
c.interval = 5.0;

7. 使用场景偏好

总结 

到此这篇关于TypeScript中type和interface区别的文章就介绍到这了,更多相关TS type和interface区别内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文