这一直困扰着我,我不知道如何解决这个问题。 基本上我有构建器类,它根据布尔构造函数值实现 true 和 false 状态,基本上如果 true,或者仅返回“this”,如果 false 我们返回参数值。
class DemoBuilder<IsTrue extends true | false> {
#isTrue: IsTrue;
constructor(isTrue: IsTrue) {
this.#isTrue = isTrue;
}
or<ValueType>(value: ValueType): IsTrue extends true ? this : ValueType {
// how to validate type "IsTrue extends true"?
if (this.#isTrue) {
return this; // Type 'this' is not assignable to type 'IsTrue extends true ? this : ValueType'.
}
return value; // Type 'ValueType' is not assignable to type 'IsTrue extends true ? this : ValueType'
}
}
您在 TypeScript 中遇到了一个常见限制,即编译器无法根据运行时值缩小泛型类型参数的范围。在您的
DemoBuilder
类中,您有一个泛型类型参数 IsTrue
,并且您希望 or
方法的返回类型取决于 IsTrue
是 true
还是 false
。
TypeScript 的类型系统不允许基于运行时检查 (
IsTrue
) 缩小泛型类型参数(在本例中为 if (this.#isTrue)
)。这意味着在方法内部,TypeScript 无法识别 IsTrue extends
truewhen
this.#isTrueis
true`。
要解决此问题,您需要使用 类型断言 通知 TypeScript 编译器您返回的值属于预期类型。以下是修改
or
方法的方法:
class DemoBuilder<IsTrue extends true | false> {
#isTrue: IsTrue;
constructor(isTrue: IsTrue) {
this.#isTrue = isTrue;
}
or<ValueType>(value: ValueType): IsTrue extends true ? this : ValueType {
if (this.#isTrue) {
return this as IsTrue extends true ? this : never;
}
return value as IsTrue extends false ? ValueType : never;
}
}
如果您希望避免类型断言,您可以重新设计类以分离
true
和 false
情况:
class DemoBuilderTrue {
or<ValueType>(value: ValueType): this {
return this;
}
}
class DemoBuilderFalse {
or<ValueType>(value: ValueType): ValueType {
return value;
}
}
type DemoBuilder<IsTrue extends boolean> = IsTrue extends true ? DemoBuilderTrue : DemoBuilderFalse;
用途:
const builderTrue: DemoBuilder<true> = new DemoBuilderTrue();
const resultTrue = builderTrue.or('some value');
const builderFalse: DemoBuilder<false> = new DemoBuilderFalse();
const resultFalse = builderFalse.or('some value');