javascript - 检测泛型类型参数是否具有 id 属性?

标签 javascript typescript generics generic-programming

我正在设计一个通用的Slice<E>表示一组实例的实例切片的类。例如,如果我们有 Todo实例,那么切片可以代表所有已完成的实例。

如果Todo类有一个 id我们要设置的属性 hasIDtrue关于Slice实例,这样我们也可以索引 Slice实例 id 。有没有办法在运行时检测通用参数是否具有 and id属性(property)?

最佳答案

如果没有代码,这里就没有太多内容可以继续。

从表面上看:不,您不可能在运行时分析泛型类型参数,因为类型系统是 erased 。在运行时,您只能分析运行时值,例如传递给构造函数的实际对象。在编译时,您可以让编译器根据泛型类型参数为 hasID 提供特定的 truefalse 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/

相关文章:

javascript - 如何移除全屏模式? (在应用浏览器中)

java - 让带有泛型实现的队列打印特定的对象属性

java - Map<A,B> foo = new HashMap<A,B>() 和 new HashMap<>() 的区别?

python - 如何访问 typing.Generic 的类型参数?

javascript - 使用 JavaScript 动态生成 @-webkit-keyframes CSS?

typescript - Angular 2 : manipulate element outside directive

javascript - 尝试包含多个js源时出错: Check your javascripts. joinTo config

typescript - 为什么我不能在 ThreeJS Typescript 项目中创建 Face3

javascript - 如何将特定的表值传递给我们从数据库表中获取的 ajax?

javascript - 仅显示 1 个 toast