检测泛型类型参数是否有 id 属性?
Detecting whether a generic type argument has an id property?
我正在设计一个通用的 Slice<E>
class,它表示一组实例中的一部分实例。例如,如果我们有 Todo
个实例,那么切片可以代表所有已完成的实例。
如果 Todo
class 有一个 id
属性 我们想在 [=17] 上将 hasID
设置为 true
=] 实例,这样我们也可以通过 id
索引 Slice
实例。有没有办法在运行时检测泛型参数是否有和 id
属性?
没有代码,这里没有太多内容可以继续。
从表面上看:不,您不可能在 运行 时分析泛型类型参数,因为类型系统是 erased。在 运行time 你只能分析 运行time 值,例如你传递给构造函数的实际对象。在编译时,您可以让编译器根据泛型类型参数将特定的 true
或 false
布尔文字类型赋予 hasID
。您可以做这两件事,并希望您有一个 运行time 值实际上与编译时类型匹配的解决方案。
我们来试试吧。这是一个可能的解决方案的草图:
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
类型参数和 returns true
如果 E['id']
存在,否则 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
。但是当然 object
可能 有一个 id
属性,所以 hasID
可能 true
在 运行时间。有办法解决这个问题吗?可能是。但这并不简单。问题是你有多大可能 运行 进入这些案例,以及你是否关心它们。
无论如何,希望这有道理并能给你一些指导。祝你好运!
我正在设计一个通用的 Slice<E>
class,它表示一组实例中的一部分实例。例如,如果我们有 Todo
个实例,那么切片可以代表所有已完成的实例。
如果 Todo
class 有一个 id
属性 我们想在 [=17] 上将 hasID
设置为 true
=] 实例,这样我们也可以通过 id
索引 Slice
实例。有没有办法在运行时检测泛型参数是否有和 id
属性?
没有代码,这里没有太多内容可以继续。
从表面上看:不,您不可能在 运行 时分析泛型类型参数,因为类型系统是 erased。在 运行time 你只能分析 运行time 值,例如你传递给构造函数的实际对象。在编译时,您可以让编译器根据泛型类型参数将特定的 true
或 false
布尔文字类型赋予 hasID
。您可以做这两件事,并希望您有一个 运行time 值实际上与编译时类型匹配的解决方案。
我们来试试吧。这是一个可能的解决方案的草图:
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
类型参数和 returns true
如果 E['id']
存在,否则 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
。但是当然 object
可能 有一个 id
属性,所以 hasID
可能 true
在 运行时间。有办法解决这个问题吗?可能是。但这并不简单。问题是你有多大可能 运行 进入这些案例,以及你是否关心它们。
无论如何,希望这有道理并能给你一些指导。祝你好运!