-
Notifications
You must be signed in to change notification settings - Fork 29
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
typescript 中的 interface 和 type 到底有什么区别? #7
Comments
type 那个不叫 extend ,那就是类型合并 type 关键字的产生的东西官方有一个名字 type aliases ,就是类型别名,重点是它是别名不是真正的类型 我发现大家好像都不是非常喜欢去看文档,其实这种基本的东西根本不用去看 spec ,文档里面就应该有 https://www.typescriptlang.org/docs/handbook/advanced-types.html#type-aliases ,它的设计意图,它的适用场景,它和 interface 的差异在文档里都明明白白的写清楚了,看完就好了 别的公司的东西不好说,微软出的很多东西文档都是写得非常好的,就去看文档就好了 |
@bolasblack 我当然知道这是类型别名,但是虽然官方定义用途不同,但实际上 interface 和 type 在某些场景下差别不大,是可以通用的,不是么?当然,滥用 type 是不好的。这其实也和 HTML 的语义化有点类同, |
@weiyu-chen 那你说说看,为什么滥用 type 是不好的…… |
其实文档里已经明明白白地写了:
这就是我为什么在开头要强调 type 的那个不叫 extend ,因为那个真的不是 extend …… |
我为了把 type 类比 interface 的 extend 行为,顺手就用 extend 了。确实,用 extend 来描述 类型别名确实不严谨,感谢勘误。
还有什么问题或者意见的欢迎提出来,共同探讨。 @bolasblack |
对总结表示不赞同。 |
@trlanfeng 这么理解倒也不能说错,但是 type/interface 到底怎么用这可能真的见仁见智了。 type 和 interface 除了官方定义不同之外,很多功能其实 用 type 和 interface 从结果上看没多大区别。 例如这篇文章interface-vs-type-alias就介绍说 type 和 interface 只要和团队保持统一就好,除了特定场景外,没有什么是必须用 interface/type 的。
|
这段代码,执行const d的时候会有错误。提示「 |
mark,插眼。 |
写过c或者go这类语言就很容易明白type了 |
// -------- base --------
type Data = Record<string, string | number>;
function fn(data: Data) {}
// -------- step one --------
type IGetUserServiceList = {
id: string;
};
let fooData: IGetUserServiceList = {
id: '12345',
};
fn(fooData);
// -------- step two --------
interface _IGetUserServiceList {
id: string;
}
let _fooData: _IGetUserServiceList = {
id: '12345',
};
// error
// 类型“_IGetUserServiceList”中缺少索引签名
fn(_fooData);
// 改为如下即可
interface __IGetUserServiceList {
// 需要增加索引签名
[k: string]: string | number;
id: string;
} 借楼打扰,关于上面的这个问题,可以解释一下么,使用 type 和 interface 定义的都是相同的对象,但是使用 interface 的时候会提示缺少索引签名,难道是 type 定义对象的时候,已经默认给予了 感谢。 |
留个名,刚开始学ts,很多不懂,向各位学习 |
个人认为两种场景可能会使用到itype而不能用interface:
|
高见 |
cy typeVSinterface |
m |
@jsjzh 我理解是这样的,借用官方文档的话 就你的例子来说, interface _IGetUserServiceList {
rich: boolean;
} 从而导致 interface _IGetUserServiceList {
rich: boolean;
id: string;
} 这时 interface __IGetUserServiceList {
// 增加索引签名后不能再加入boolean属性
[k: string]: string | number;
id: string;
}
interface __IGetUserServiceList {
rich: boolean // error
} 总结一下,type关键字声明的type在创建后是不可变的。而interface在创建后是可变的,但是这种可变性可以通过索引签名来约束。 |
个人角度,type alias 语法上更像代数数据类型,或许会受到喜欢函数式编程的程序员青睐。例如 type student = [string, number]; 可以看做元组,type student = {name: string, old: number} 可以看做命名元组。 a & b 可以看做 a 和 b 类型的积(product), a | b 可以看做 a 和 b 类型的和(sum)。 |
type TestA = A extends StringMap ? A : never
// TestA = never
type TestB = B extends StringMap ? B : never
// TestB = B |
两者都是为了告诉编译器,如何理解某个字段的结构类型 但两者的定义和使用场景还是有区别的:
所以,在描述带关系的数据结构时,interface应该优先于type被考虑,甚至可以简化思考,直接上interface。而type在一定程度上简化类型描述,例如,type StrOrNum = string | number,后面都可以复用StrOrNum去代表string | number,如果在一个类型描述文件里,string | number这样的类型字段比较多,就可以用type去精简内容。 |
我觉得创造类型的与集使用interface,使用类型的或集使用type。与集与其说是类型,更应该说是类,只不过这里不需要实例(或者说不需要prototype)。 |
尽量多用type可以省去很多麻烦 |
|
mark |
不觉得是好的设计,我认为只保留type就可以了。类型合并这种场景很少,用了也容易滋生bug |
从写后端角度。比如:go,给我的感觉是: |
个人感觉 |
如果你是一个人写只给自己看的代码,那可以闭着眼睛只用 interface User {
name: string,
}
/*
User interface itself now has been changed!
*/
interface User {
sex: string,
} 这跟js中从头到尾用一个变量a来接收所有值是一个性质——只要不用维护,怎么写都是你的自由。 事实上,
但是如果用不到这些强大的能力,那么还是用 |
这个 heuristic 如何来理解呢?这句话我理解起来,官方倒是比较侧重于前面的那句话,就是你喜欢用哪个就用哪个。 |
interface VS type
大家使用 typescript 总会使用到 interface 和 type,官方规范 稍微说了下两者的区别
明人不说暗话,直接上区别。
相同点
都可以描述一个对象或者函数
interface
type
拓展(extends)与 交叉类型(Intersection Types)
interface 可以 extends, 但 type 是不允许 extends 和 implement 的,但是 type 缺可以通过交叉类型 实现 interface 的 extend 行为,并且两者并不是相互独立的,也就是说 interface 可以 extends type, type 也可以 与 interface 类型 交叉 。
虽然效果差不多,但是两者语法不同。
interface extends interface
type 与 type 交叉
interface extends type
type 与 interface 交叉
不同点
type 可以而 interface 不行
interface 可以而 type 不行
interface 能够声明合并
总结
一般来说,如果不清楚什么时候用interface/type,能用 interface 实现,就用 interface , 如果不能就用 type 。其他更多详情参看 官方规范文档
The text was updated successfully, but these errors were encountered: