如何解析扩展类型?

问题描述 投票:0回答:1

这一直困扰着我,我不知道如何解决这个问题。 基本上我有构建器类,它根据布尔构造函数值实现 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
1个回答
0
投票

您在 TypeScript 中遇到了一个常见限制,即编译器无法根据运行时值缩小泛型类型参数的范围。在您的

DemoBuilder
类中,您有一个泛型类型参数
IsTrue
,并且您希望
or
方法的返回类型取决于
IsTrue
true
还是
false

TypeScript 的类型系统不允许基于运行时检查 (

IsTrue
) 缩小泛型类型参数(在本例中为
if (this.#isTrue)
)。这意味着在方法内部,TypeScript 无法识别
IsTrue extends
true
when
this.#isTrue
is
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');
© www.soinside.com 2019 - 2024. All rights reserved.