Typescript 的条件: T extends U ? X : Y
语法非常强大,但是我还没有找到一种方法来根据类的属性或函数本身的某些内容来指定返回的类型。例如,采取这个简单的类:
class X {
members: number[] = [];
returnRoman = false;
first(): number|string {
if (!this.returnRoman) {
return members[0];
} else {
return numberToRomanNumeral(members[0]);
}
}
}
有没有办法将返回的类型缩小为简单的数字或字符串以进行类型检查?我遇到的特殊问题是我有这样的结构:
class Base {
x: number = 0;
}
class Sub extends Base {
y: number = 0;
}
class FilterIterator {
members: Base[] = [];
filterClass: typeof Base = undefined;
class first(): Base {
for (const m of this.members) {
if (this.filterClass !== undefined && !(m instanceof this.filterClass)) {
continue;
}
return m;
}
}
}
const fi = FilterIterator();
fi.filterClass = Sub
fi.members = [new Sub(), new Sub()];
const s = fi.first();
if (s.y > 0) {
console.log('s is moving up in the world!');
}
因为fi.first()
输入为 return Base
,所以该行if (s.y > 0)
引发错误,因为y
Base 上不存在。在这种情况下,它不会太难做到:
const s = fi.first() as Sub;
但如果我们有这样的东西:
class FilterIterator extends Base {
...
filterClass = FilterIterator; // I know, not possible simply, but there are ways...
}
然后你最终得到如下代码:
const fi = FilterIterator();
[ set up .members with nested FilterIterators ]
const firstOfFirstOfFirst = fi.first().first().first();
被改写为:
const firstOfFirstOfFirst = (((fi.first() as FilterIterator).first()
as FilterIterator).first() as FilterIterator);
如果我们实际上创建可以返回生成器等的生成器,情况会变得更糟,因为在for...of
循环中声明类型是不可能的。它还将确定返回值应该是什么的逻辑转移到使用软件,FilterIterator 或 Base 本身应该知道可能返回哪些类。
欢迎任何解决方案或改进。