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
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")