条件类型无法识别所有输入都会产生相同的条件结果
Conditional type doesn't recognize that all inputs result in same conditional result
这个例子没有类型检查:
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);
}
错误是因为 extra
在 doSubset1Thing
中被硬编码 string
,但逻辑上它 是 总是一个字符串,因为 value
仅限于 Subset1
,Extra<Subset1>
正确解析为 string
,但出于某种原因,对 doThing
的调用无法识别。
同样,即使第三个参数始终为 undefined
.
,也会为 doSubset2Thing
错误反转它
对于第二个,如果 Subset1
和 Subset2
重叠,我可以看到一些问题,但它们没有重叠,所以我假设 TS 会把这一切都弄平undefined
对于 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 {
// ...
}
这个例子没有类型检查:
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);
}
错误是因为 extra
在 doSubset1Thing
中被硬编码 string
,但逻辑上它 是 总是一个字符串,因为 value
仅限于 Subset1
,Extra<Subset1>
正确解析为 string
,但出于某种原因,对 doThing
的调用无法识别。
同样,即使第三个参数始终为 undefined
.
doSubset2Thing
错误反转它
对于第二个,如果 Subset1
和 Subset2
重叠,我可以看到一些问题,但它们没有重叠,所以我假设 TS 会把这一切都弄平undefined
对于 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 {
// ...
}