我正在设计一个通用的Slice<E>
表示一组实例的实例切片的类。例如,如果我们有 Todo
实例,那么切片可以代表所有已完成的实例。
如果Todo
类有一个 id
我们要设置的属性 hasID
至true
关于Slice
实例,这样我们也可以索引 Slice
实例 id
。有没有办法在运行时检测通用参数是否具有 and id
属性(property)?
最佳答案
如果没有代码,这里就没有太多内容可以继续。
从表面上看:不,您不可能在运行时分析泛型类型参数,因为类型系统是 erased 。在运行时,您只能分析运行时值,例如传递给构造函数的实际对象。在编译时,您可以让编译器根据泛型类型参数为 hasID
提供特定的 true
或 false
bool 文字类型。您可以完成这两件事,并希望您得到一个运行时值实际上与编译时类型匹配的解决方案。
我们来试试吧。以下是可能的解决方案的草图:
class Slice<E> {
instances: E[]
hasID: E extends {id: any} ? true : false;
constructor(firstInstance: E, ...restInstances: E[]) {
this.hasID = 'id' in firstInstance as Slice<E>['hasID'];
this.instances = [firstInstance, ...restInstances];
}
}
hasID
属性被赋予 conditional type它评估 E
类型参数,如果 E['id']
存在,则返回 true
,否则返回 false
。
构造函数至少接受一个 E
类型的参数,其中第一个参数在运行时分析 id
属性,以便设置 hasID
运行时值。
让我们看看它是否有效:
const sliceOne = new Slice({a: 1}, {a: 2});
sliceOne.hasID // false at compile time and runtime
const sliceTwo = new Slice({id: 1}, {id: 2});
sliceTwo.hasID // true at compile time and runtime
看起来不错。您仍然可能需要担心一些边缘情况,例如:
declare const notSure: object;
const oopsie = new Slice(notSure);
oopsie.hasID; // false at compile time, maybe true at runtime!
编译器无法验证 object
是否具有 id
属性,因此它为 hasID
提供类型 false
。但是,当然对象
可能有一个id
属性,所以也许hasID
将是true
在运行时。有办法解决这个问题吗?或许。但这并不简单。问题是您遇到这些情况的可能性有多大以及您是否关心它们。
无论如何,希望这是有道理的并给你一些方向。祝你好运!
关于javascript - 检测泛型类型参数是否具有 id 属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52123719/