log*_*yth 7 typescript conditional-types
此示例不进行类型检查:
type Subset1 = "one" | "two";
type Subset2 = "three" | "four";
type All = Subset1 | Subset2;
type Other = {
"one": number,
"two": string,
"three": boolean,
"four": object,
};
type Extra<V> = V extends Subset1 ? string : undefined;
function doOtherThing(stuff: string){}
function doThing<V extends All>(value: V, params: Other[V], extra: Extra<V>) { }
function doSubset1Thing<V extends Subset1>(value: V, params: Other[V], extra: string) {
doThing(value, params, extra);
doOtherThing(extra);
}
function doSubset2Thing<V extends Subset2>(value: V, params: Other[V]) {
doThing(value, params, undefined);
}
Run Code Online (Sandbox Code Playgroud)
( TS 游乐场)
这个错误是因为extra被硬编码string在doSubset1Thing,但在逻辑上它是始终是一个字符串,因为value被限制Subset1,并Extra<Subset1>正确解析到string,但由于某些原因,调用doThing不承认。
同样,doSubset2Thing即使第三个参数始终是undefined.
对于第二个,如果Subset1和Subset2重叠,我可以看到一些问题,但它们没有,所以我假设 TS 会将所有内容都归结为undefinedfor doSubset2Thing。
有什么办法可以使这项工作?或者,我是否错过了实际上确实使此无效的内容?
据我所知,在这种情况下,您的代码在逻辑上是正确且类型安全的,但 Typescript 无法证明这一点,因为它缺乏能够证明这一点的规则。像“V必须扩展,Subset1因为这是它的上限”这样的简单规则就足够了,但显然 Typescript(当前)没有编程为使用这样的规则。
一个修复方法是使用函数重载,这对于您的用例来说可能比条件类型更有意义:这也使您不必undefined在第二种情况下传递显式的。
function doThing<V extends Subset1>(value: V, params: Other[V], extra: string): void;
function doThing<V extends Subset2>(value: V, params: Other[V]): void;
function doThing<V extends All>(value: V, params: Other[V], extra?: string): void {
// ...
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
56 次 |
| 最近记录: |