react 中 useObservable 钩子的可选通用选择函数

问题描述 投票:0回答:1

我有用于 rxjs 可观察量的自定义通用钩子。现在看起来像这样:

type Params<T> = {
  observable$: Observable<T> | null;
  next: (value: T) => void;
};

export const useSubscription = <T>({
  observable$,
  next,
}: Params<T>) => {
  const nextCallback = useCallbackRef(next);

  useEffect(() => {
    if (!observable$) {
      return undefined;
    }

    const sub = observable$.subscribe(nextCallback);

    return () => sub.unsubscribe();
  }, [observable$, nextCallback]);
};

它工作正常,但现在我正在尝试向

select
添加可选的通用
Params
功能。我打算将它与 rxjs
map
运算符一起使用。
select
应将
T
作为输入并返回某种类型
R
,然后将其传递给
next
函数。如果未提供
select
,则
next
的输入类型应为之前的
T
。因此,可能的参数选项大致应如下所示:

type Params<T, R> = {
  observable$: Observable<T> | null;
  next: (value: T) => void;
} | {
  observable$: Observable<T> | null;
  next: (value: R) => void;
  select: (value: T) => R;
};

我尝试使用条件类型、函数重载来实现此目的,但无法实现。

typescript react-hooks typescript-generics
1个回答
0
投票

请参阅下面的一些解释:

type ParamsA<T> = {
  observable$: T;
  next: (value: T) => void;
}

type ParamsB<T, R> = {
  observable$: T;
  next: (value: R) => void;
  select: (value: T) => R;
}

type Params<T, R = undefined> = R extends undefined ? ParamsA<T> : ParamsB<T, R>;

const a: Params<number> = {
  observable$: 1,
  next: (value) => { console.log(value); },
} // OK: value --> number

const b: Params<number, string> = {
  observable$: 1,
  next: (value) => { console.log(value); },
} // ERROR: Property 'select' is missing in type '{ observable$: number; next: (value: string) => void; }' but required in type 'ParamsB<number, string>'

const c: Params<number, string> = {
  observable$: 1,
  next: (value) => { console.log(value); },
  select: (value) => 'a',
} // OK: next value --> string, select value --> number

const d: Params<number> = {
  observable$: 1,
  next: (value) => { console.log(value); },
  select: (value) => 'a',
} // ERROR: Object literal may only specify known properties, and 'select' does not exist in type 'ParamsA<number>'.

因此,我们将

Params
分成它可以采用的两种可能的形式,并使用 条件类型 来根据是否传递了泛型参数
R
来确定哪一种形式。通过将 R 参数的
默认值
设置为未定义,它变成可选的,从而使
select
属性仅在传递
R
时才需要。

© www.soinside.com 2019 - 2024. All rights reserved.