TypeScript中的这些语句(接口与类型)有什么区别?
interface X {
a: number
b: string
}
type X = {
a: number
b: string
};
TypeScript中的这些语句(接口与类型)有什么区别?
interface X {
a: number
b: string
}
type X = {
a: number
b: string
};
当前回答
根据我最近看到或参与的所有讨论,类型和接口之间的主要区别在于接口可以扩展,而类型不能扩展。
此外,如果您两次声明一个接口,它们将被合并为一个接口。你不能用打字。
其他回答
接口与类型
接口和类型用于描述对象和原语的类型。接口和类型通常可以互换使用,并且通常提供类似的功能。通常由程序员选择自己的偏好。
然而,接口只能描述创建这些对象的对象和类。因此,必须使用类型来描述字符串和数字等原语。
下面是接口和类型之间的两个区别的示例:
// 1. Declaration merging (interface only)
// This is an extern dependency which we import an object of
interface externDependency { x: number, y: number; }
// When we import it, we might want to extend the interface, e.g. z:number
// We can use declaration merging to define the interface multiple times
// The declarations will be merged and become a single interface
interface externDependency { z: number; }
const dependency: externDependency = {x:1, y:2, z:3}
// 2. union types with primitives (type only)
type foo = {x:number}
type bar = { y: number }
type baz = string | boolean;
type foobarbaz = foo | bar | baz; // either foo, bar, or baz type
// instances of type foobarbaz can be objects (foo, bar) or primitives (baz)
const instance1: foobarbaz = {y:1}
const instance2: foobarbaz = {x:1}
const instance3: foobarbaz = true
根据我最近看到或参与的所有讨论,类型和接口之间的主要区别在于接口可以扩展,而类型不能扩展。
此外,如果您两次声明一个接口,它们将被合并为一个接口。你不能用打字。
除了已经提供的出色答案之外,在扩展类型和接口方面还有明显的区别。我最近遇到了一些界面无法完成任务的情况:
无法使用接口扩展联合类型无法扩展通用接口
索引的差异。
interface MyInterface {
foobar: string;
}
type MyType = {
foobar: string;
}
const exampleInterface: MyInterface = { foobar: 'hello world' };
const exampleType: MyType = { foobar: 'hello world' };
let record: Record<string, string> = {};
record = exampleType; // Compiles
record = exampleInterface; // Index signature is missing
相关问题:类型中缺少索引签名(仅在接口上,而不是在类型别名上)
因此,如果您想为对象编制索引,请考虑这个示例
看看这个问题和这个关于违反利斯科夫原则的问题
评估中的差异
当FirstLevelType为接口时,请查看ExtendeFirst的结果类型
/**
* When FirstLevelType is interface
*/
interface FirstLevelType<A, Z> {
_: "typeCheck";
};
type TestWrapperType<T, U> = FirstLevelType<T, U>;
const a: TestWrapperType<{ cat: string }, { dog: number }> = {
_: "typeCheck",
};
// { cat: string; }
type ExtendFirst = typeof a extends FirstLevelType<infer T, infer _>
? T
: "not extended";
当FirstLevelType为类型时,请查看ExtendeFirst的结果类型:
/**
* When FirstLevelType is type
*/
type FirstLevelType<A, Z>= {
_: "typeCheck";
};
type TestWrapperType<T, U> = FirstLevelType<T, U>;
const a: TestWrapperType<{ cat: string }, { dog: number }> = {
_: "typeCheck",
};
// unknown
type ExtendFirst = typeof a extends FirstLevelType<infer T, infer _>
? T
: "not extended";
TypeScript手册给出了答案:
界面的几乎所有功能都是可用的类型。关键区别在于不能重新打开类型以添加新的财产vs始终可扩展的接口。