typescript - 为什么下面的 TypeScript 程序不抛出类型错误?
问题描述
考虑以下程序。
interface Eq<A> {
eq(this: A, that: A): boolean;
};
class Pair<A> implements Eq<Pair<A>> {
constructor(public x: A, public y: A) {}
eq(this: Pair<A>, that: Pair<A>): boolean {
return this.x === that.x && this.y === that.y;
}
}
class Triple<A> implements Eq<Triple<A>> {
constructor(public x: A, public y: A, public z: A) {}
eq(this: Triple<A>, that: Triple<A>): boolean {
return this.x === that.x && this.y === that.y && this.z === that.z;
}
}
const eq = <A extends Eq<A>>(x: A, y: A): boolean => x.eq(y);
console.log(eq(new Pair(1, 2), new Triple(1, 2, 3)));
console.log(eq(new Triple(1, 2, 3), new Pair(1, 2)));
我原以为 TypeScript 编译器会抱怨最后两行,因为您不应该将eq
函数应用于不同类型的两个值。但是,TypeScript 编译器不会为上述程序抛出任何类型错误。上述程序的结果是true
和false
。
为什么 TypeScript 编译器不会为上述程序抛出类型错误?我们怎样才能让它正确地捕捉到这些类型的错误呢?
解决方案
该程序的编译是由于TypeScript 中使用的结构子类型(与其他编程语言中经常出现的名义子类型相反)。
请注意,您的Triple
类是可以分配给类型变量的Pair
:
const p: Pair<number> = new Triple(1, 2, 3);
在您的示例中:
console.log(eq(new Pair(1, 2), new Triple(1, 2, 3)));
console.log(eq(new Triple(1, 2, 3), new Pair(1, 2)));
的类型eq
推断为:
const eq: <Pair<number>>(x: Pair<number>, y: Pair<number>) => boolean
如上所示,Triple
是类型参数的有效参数Pair
,因此一切都可以干净地编译。
您可以向您的类添加不同的私有字段来模拟名义子类型。在此特定示例中,您可以选择以下两个选项之一:
- 添加额外的标记字段
- make
x
,y
,z
private 并提供 getter
推荐阅读
- excel - Pulling multiple criteria from another cell
- python - How to split a string based on the
tag using beautifulsoup - android - 有没有办法在没有受支持的设备的情况下开发 ARCore?
- ios - 快速将图像上传到 FTP 服务器
- java - 在没有 View Resolver 的情况下重定向到 spring-boot-starter-webflux 中的外部绝对 URL
- c# - 如何使用 Windows 服务调用浏览器选项卡
- android - 使用 Firebase 在我的 android 应用程序中验证两种类型的用户(学生和司机)的最佳方法是什么
- jquery - 我想从 gridview 中拖动一行并将其放在 treeview 上
- python-3.x - python3上numpy中float32数字的矩阵乘法不稳定性
- laravel-5.7 - Laravel 内部 API 调用控制器重定向到 localhost 后