Вот несколько упрощенная версия определений для Knockout subscribable
:
export type SubscriptionCallback<T = any, TTarget = void> = (this: TTarget, val: T) => void;
export interface Subscription {
dispose(): void;
}
export interface SubscribableFunctions<T = any> extends Function {
init<S extends Subscribable<any>>(instance: S): void;
notifySubscribers(valueToWrite?: T, event?: string): void;
// This definition is wrong
subscribe<TTarget = void>(callback: SubscriptionCallback<Array<ArrayChange<T>>, TTarget>, callbackTarget: TTarget, event: "arrayChange"): Subscription;
subscribe<TTarget = void>(callback: SubscriptionCallback<T, TTarget>, callbackTarget?: TTarget, event?: "change"): Subscription;
subscribe<X = any, TTarget = void>(callback: SubscriptionCallback<X, TTarget>, callbackTarget: TTarget, event: string): Subscription;
extend(requestedExtenders: ObservableExtenderOptions): this;
extend<S extends Subscribable<any>>(requestedExtenders: ObservableExtenderOptions): S;
getSubscriptionsCount(event?: string): number;
}
export interface Subscribable<T = any> extends SubscribableFunctions<T> { }
export interface ArrayChange<T = any> {
status: "added" | "deleted" | "retained";
value: T;
index: number;
moved?: number;
}
Проблема в том, что определение обратного вызова для события arrayChange
неверно.Во-первых, событие arrayChange
должно применяться, только если T
является массивом, скажем, X[]
.Тогда значение, используемое интерфейсом ArrayChange
, должно быть типа X
, а не X[]
.
Как включить подпись события arrayChange
, только если T
является массивом ибыть в состоянии извлечь базовый тип?