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
};
当前回答
文件已经解释了
一个区别是,接口创建了一个新名称,该名称在任何地方都可以使用。类型别名不会创建新名称-例如,错误消息不会使用别名名称。在旧版本的TypeScript中,类型别名无法从扩展或实现(也无法扩展/实现其他类型)。从2.7版起,可以通过创建新的交叉点类型来扩展类型别名另一方面,如果不能用接口表达某种形状,并且需要使用联合或元组类型,则通常使用类型别名。
接口与类型别名
其他回答
文件已经解释了
一个区别是,接口创建了一个新名称,该名称在任何地方都可以使用。类型别名不会创建新名称-例如,错误消息不会使用别名名称。在旧版本的TypeScript中,类型别名无法从扩展或实现(也无法扩展/实现其他类型)。从2.7版起,可以通过创建新的交叉点类型来扩展类型别名另一方面,如果不能用接口表达某种形状,并且需要使用联合或元组类型,则通常使用类型别名。
接口与类型别名
就编译速度而言,组合接口的性能优于类型交集:
[…]接口创建检测属性冲突的单个平面对象类型。这与交叉点类型不同,在交叉点类型中,在对照有效类型进行检查之前,检查每个组成部分。接口之间的类型关系也被缓存,而不是交叉类型。
资料来源:https://github.com/microsoft/TypeScript/wiki/Performance#preferring-交叉口上的接口
根据我最近看到或参与的所有讨论,类型和接口之间的主要区别在于接口可以扩展,而类型不能扩展。
此外,如果您两次声明一个接口,它们将被合并为一个接口。你不能用打字。
接口与类型
接口和类型用于描述对象和原语的类型。接口和类型通常可以互换使用,并且通常提供类似的功能。通常由程序员选择自己的偏好。
然而,接口只能描述创建这些对象的对象和类。因此,必须使用类型来描述字符串和数字等原语。
下面是接口和类型之间的两个区别的示例:
// 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";