打字稿:将 typeof 与泛型结合使用

时间:2021-03-10 10:15:51

标签: typescript generics

我有以下场景:

// Some library
interface Bar<T> {
  something: T
}

export function foo<T>(b: Bar<T>) {}

// In my code
function anotherFoo(param1: ???) {
  MyLib.foo(param1);
}

哪里???是我的未知

Bar 没有导出,所以我凭直觉试过:

type param<T> = Parameters<typeof foo<T>>[0];

function anotherFoo<X>(param1: param<X>) {
  MyLib.foo(param1);
}

但是 type 定义是非法的。

使用 type param = Parameters<typeof foo>[0];typeof 似乎推断 unknown,即 Bar<unknown>

??? 应该是什么?

编辑:我的实际情况

import { Observable, of } from 'rxjs';
import { useDispatch, useSelector } from 'react-redux';

type Items = string[];
interface AppStore {
    items: Items
}

type SelectFn = Parameters<typeof useSelector>[0];

function useSelectorAsStream<T>(selectFn: SelectFn) {
    const items = useSelector<AppStore, T>(selectFn);
    const obs: Observable<T> = of(items);
    return obs;
}

function PartialReactComponent() {
    const myItems: Observable<Items> = useSelectorAsStream<Items>(store => store.items);
}

1 个答案:

答案 0 :(得分:2)

我相信这对你有用:

import { Observable, of } from 'rxjs';
import { useDispatch, useSelector } from 'react-redux';

type Items = string[];
interface AppStore {
    items: Items
}

type SelectFn<T> = (state: AppStore) => T

function useSelectorAsStream<T>(selectFn: SelectFn<T>) {
    const items = useSelector<AppStore, T>(selectFn);
    const obs: Observable<T> = of(items);
    return obs;
}

function PartialReactComponent() {
    const myItems = useSelectorAsStream<Items>(store => store.items);
}

Playground

更新

为了安全使用 typeof:

import { Observable, of } from 'rxjs';
import { useDispatch, useSelector } from 'react-redux';

type Items = string[];
interface AppStore {
    items: Items
}

type SelectFn<T> = (state: AppStore) => T

type Result<T> =
    typeof useSelector extends <State, Selected>(cb: SelectFn<T>) => T
    ? SelectFn<T>
    : never


function useSelectorAsStream<T>(selectFn: Result<T>) {
    const items = useSelector<AppStore, T>(selectFn);
    const obs: Observable<T> = of(items);
    return obs;
}

function PartialReactComponent() {
    const myItems: Observable<Items> = useSelectorAsStream<Items>(store => store.items);
}