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
};
当前回答
文档中指出的关键区别在于,可以重新打开接口以添加新属性,但不能重新打开类型别名以添加新的属性,例如:
这没问题
interface x {
name: string
}
interface x {
age: number
}
这将抛出错误Duplicate identifier y
type y = {
name: string
}
type y = {
age: number
}
除此之外,接口和类型别名类似。
其他回答
根据我最近看到或参与的所有讨论,类型和接口之间的主要区别在于接口可以扩展,而类型不能扩展。
此外,如果您两次声明一个接口,它们将被合并为一个接口。你不能用打字。
除了已经提供的出色答案之外,在扩展类型和接口方面还有明显的区别。我最近遇到了一些界面无法完成任务的情况:
无法使用接口扩展联合类型无法扩展通用接口
文件已经解释了
一个区别是,接口创建了一个新名称,该名称在任何地方都可以使用。类型别名不会创建新名称-例如,错误消息不会使用别名名称。在旧版本的TypeScript中,类型别名无法从扩展或实现(也无法扩展/实现其他类型)。从2.7版起,可以通过创建新的交叉点类型来扩展类型别名另一方面,如果不能用接口表达某种形状,并且需要使用联合或元组类型,则通常使用类型别名。
接口与类型别名
想加上我的2美分;
我曾经是“界面爱好者”(除了联合、交叉等以外,我更喜欢界面而不是类型)。。。直到我开始使用类型“any key value object”,即Record<string,unknown>
如果键入“任意键值对象”:
function foo(data: Record<string, unknown>): void {
for (const [key, value] of Object.entries(data)) {
// whatever
}
}
如果你使用接口,你可能会走到死胡同
interface IGoo {
iam: string;
}
function getGoo(): IGoo {
return { iam: 'an interface' };
}
const goo = getGoo();
foo(goo); // ERROR
// Argument of type 'IGoo' is not assignable to parameter of type
// 'Record<string, unknown>'.
// Index signature for type 'string' is missing in type
// 'IGoo'.ts(2345)
虽然打字就像一个符咒:
type Hoo = {
iam: string;
};
function getHoo(): Hoo {
return { iam: 'a type' };
}
const hoo = getHoo();
foo(hoo); // works
这个特定的用例——IMO——产生了不同。
还有一个不同之处。我会的。。。如果你能解释这种情况的原因,请给你买一杯啤酒:
enum Foo { a = 'a', b = 'b' }
type TFoo = {
[k in Foo]: boolean;
}
const foo1: TFoo = { a: true, b: false} // good
// const foo2: TFoo = { a: true } // bad: missing b
// const foo3: TFoo = { a: true, b: 0} // bad: b is not a boolean
// So type does roughly what I'd expect and want
interface IFoo {
// [k in Foo]: boolean;
/*
Uncommenting the above line gives the following errors:
A computed property name in an interface must refer to an expression whose type is a
literal type or a 'unique symbol' type.
A computed property name must be of type 'string', 'number', 'symbol', or 'any'.
Cannot find name 'k'.
*/
}
// ???
这种情况让我很想说接口的问题,除非我有意实现一些OOP设计模式,或者需要如上所述的合并(除非我有充分的理由,否则我永远不会这么做)。