Search code examples
typescript

how to resolving extends type?


This have been bugging me and I can't figure out how of if I can resolve this. Basically I have builder class which implements both true and false states based on boolean constructor value, basically if true, or returns just "this", if false we return argument value.

type MappedType<IsTrue extends boolean, TrueType, FalseType> = { true: TrueType; false: FalseType }[`${IsTrue}`];

function asMapped<IsTrue extends boolean, TrueType, FalseType>(isTrue: IsTrue, trueValue: TrueType, falseValue: FalseType): MappedType<IsTrue, TrueType, FalseType> {
  return { true: trueValue, false: falseValue }[`${isTrue}`];
}

class OptionBuilder<IsTrue extends boolean, SomeType = unknown> {
  #isTrue: IsTrue;
  #value: SomeType;
  constructor(isTrue: IsTrue, someType: SomeType) {
    this.#isTrue = isTrue;
    this.#value = someType;
  }
  or<ValueType>(value: ValueType): MappedType<IsTrue, this, ValueType> {
    return asMapped<IsTrue, this, ValueType>(this.#isTrue, this, value);
  }
}

const ex1 = new OptionBuilder(false, undefined);
const ex2 = new OptionBuilder(true, 'value');

const ex3 = ex1.or("hello")
const ex4 = ex2.or("hello")

Edit: Fixed code with helper function and type


Solution

  • If we use mapped types then we can do this.

    class DemoBuilder<IsTrue extends boolean> {
      #isTrue: IsTrue;
      constructor(isTrue: IsTrue) {
        this.#isTrue = isTrue;
      }
      or<ValueType>(value: ValueType) {
        const objThis: DemoBuilder<IsTrue> = this;
        return { true: objThis, false: value }[`${this.#isTrue}`];
      }
    }
    
    const ex1 = new DemoBuilder(false);
    const ex2 = new DemoBuilder(true);
    
    const ex3 = ex1.or("hello")
    const ex4 = ex2.or("hello")