Open tscpp opened 2 weeks ago
Simply unwrapping the observable won't work because the observable is a function. According to typescript, functions are nondeterministic, meaning that we can't expect the same return value.
const foo = ko.observable<string | undefined>();
if (foo() !== undefined) {
const bar = foo();
bar // string | undefined
}
The if/ifnot bindings should return a new child context where it extracts all the truthy values from the observable.
declare function binding<T>(value: ko.Observable<T>): ko.Observable<Extract<T, {}>>;
const foo = ko.observable<string | undefined>();
const bar = binding(foo); // extracts thruthy values
const baz = bar();
baz // string
This is a problem because we can't know what condition is passed to the if/ifnot bindings. In the below example, we expect name to be ko.Observable<string>
since we checked if the value is not null.
<!-- ko if: name() !== null -->
Hello <span data-bind="text: name"></span>!
<!-- /ko -->
The below example unfortunately does not work since foo will only recieve an overload. So the type will become (): string | undefined
& (): string
. The return value from this type is string | undefined
. In conclusion, asserting the observable will not work.
const foo = ko.observable<string | undefined>();
assert<ko.Observable<string>>(foo);
const bar = foo();
bar // string | undefined
A solution to this would be to assert all instances of the observable in the descendants of the binding. The downside is that this would probably require a lot of work and slow down the transpiler even more.
const foo = ko.observable<string | undefined>();
const bar = foo() as string;
bar // string
Issue is open to suggestions!