您如何推断泛型类的泛型要求(扩展部分中的内容)?
// UserGivenClassThatCouldHaveAnyGeneric
class A<T extends string> {
constructor(a: T) {}
}
我如何推断通用T
必须扩展string
。我需要在条件声明中提供此信息。
我尝试了以下
type E<W> = any extends A<infer T> ? W extends T ? A<W> : void : void
E
在给定W
不扩展T
要求的情况下应该为空,但在给定from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Firefox()
driver.get("http://somedomain/url_that_delays_loading")
try:
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, "myDynamicElement"))
)
finally:
driver.quit()
的情况下应为A。但是,即使没有显示语法错误警告,这也根本不起作用。
答案 0 :(得分:1)
我的建议是将E<W>
更改为以下内容:
type E<W> = never extends A<infer T> ? [W] extends [T] ? A<W> : void : never
首先,大多数类型any
的条件类型(其中选中的类型为any extends X ? Y : Z
,例如Y | Z
,最终将被视为联合X
。也就是说,any
在特殊情况下可以接受条件类型的两个分支。有关此问题的讨论,请参见microsoft/TypeScript#27418。假设您仅尝试使用条件类型的true分支,那么最好使用never extends X ? Y : Z
。通常,never extends X
将始终为true,然后结果将为Y
。另外,如果您不想担心工会混乱,可以将其设置为never
,而不是void
。类型A | never
的计算结果为A
,而A | void
的计算结果通常不是。
因此,我们将type E<W> = any extends A<infer T> ? W extends T ? A<W> : void : void
更改为type E<W> = never extends A<infer T> ? W extends T ? A<W> : void : never
。
现在剩下的问题是:如果W
本身是联合类型,您想做什么?如果您将E<W>
定义为W extends T
而不是[W] extends [T]
,它将被视为distributive conditional type。这意味着,如果W
是类似于A | B | C
的联合类型,则E<W>
将评估该联合的每个成员的条件并将结果统一,从而产生等效结果E<A> | E<B> | E<C>
中的。也许这就是您想要的,但可能不是。毕竟,如果W
是string | number
,您可能想让void
出来,而不是A<string> | void
,对吗?
条件类型何时成为分布的规则是,您正在检查“裸”或“裸”通用类型参数。由于W
是泛型类型参数,因此条件类型W extends T ? ...
将是分布式的。关闭此行为的最简单方法是用一些协变变量“覆盖”类型参数,例如单元素元组类型。这样就变成了[W] extends [T] ? ...
。
好的,希望能有所帮助;祝你好运!