knockout
knockout copied to clipboard
Types: Add types for ReadonlyObservable, ReaonlyObservableArray, ReadonlyComputed
This adds types for representing immutable versions of observables, observable arrays, and computeds. The changes in this PR match changes that were introduced into the public typings in DefinitelyTyped/DefinitelyTyped#30499.
Although the underlying objects may actually be mutable, it's frequently useful to treat them as if they weren't: functions can accept readonly versions to indicate that they won't modify the contents, or things can be made publicly immutable, while still being privately mutable.
class Counter {
value: ReadonlyObservable<number>;
incr: () => void;
constructor() {
const value = this.value = ko.observable(0);
this.incr = () => value(value.peek() + 1);
}
}
The consumer can read the value, subscribe to it, or call incr to increment it, but they can't set arbitrary values without circumventing the types.
Additionally, while Computed<T> is no longer assignable to Observable<T> like it was in the public typings (missing the '.willMutate' methods and the '.valueHasMutatedand.valueWillMutatemethods), a computed is assignable toReadonlyObservable<T>`, which is convenient for functions like:
function logChanges(observable: ReadonlyObservable<any>);
instead of:
function logChanges(observable: KnockoutObservable<any> | KnockoutComputed<any>);
In theory, certain overrides of ko.computed should return readonly computeds, not writable computeds:
const five = ko.computed(() => 5)
five(6); // Runtime error but not type error
This PR does not address that issue. It never was addressed in the public typings - it caused a prohibitive number of type errors in our project, but it might be a smoother transition here. (A lot of the 'prohibitive errors' are type errors we're going to need to fix to go from 3.4 to 3.5 anyway)
@Retsam I've made some changes in #2563. Let me know what you think.