javascript - Typescript 中带有函数的映射类型

标签 javascript typescript redux reselect

我在使用映射类型时遇到了一些问题。

我正在尝试输入一个组成 redux“选择器”的函数(本质上只是来自 A => B 的函数)

我的目标 API 基本上是:

const bar = composeSelectors([
  (s: string) => s.length,
  (s: string) => s.trim(),
])

bar // should be (s: string) => [number, string]

这是我到目前为止所得到的:

type Selector<A, Z> = (a:A) => Z
type Selected<T> = T extends Selector<any, infer U> ? U : never;
type MappedSelector<S, T> = Selector<S, { [Y in keyof T]: Selected<T[Y]> }>

const selectedNumber: Selected<Selector<string, number>> = null as any
selectedNumber // is number

const baz: MappedSelector<string, [Selector<string, number>, Selector<string, string>]> = null as any
baz  // is Selector<string, [number, string]> !!!

这似乎工作得很好,直到我尝试在函数中使用MappedSelector:

type InferableMappedSelector<S> = <T extends any[]>(...values: T) => MappedSelector<S, T>
function createInferredSelector<S>(): InferableMappedSelector<S> {...}
const inferredSelectorCreator = createInferredSelector<string>()


const fooSelector: Selector<string, number> = s => s.length;
const barSelector: Selector<string, string> = s => s.trim();
const selectors: [Selector<string, string>, Selector<string, number>] = [barSelector, fooSelector]

const baz = inferredSelectorCreator(selectors)
baz // is Selector<string, [never]>, not Selector<string, [number, string]>

我也尝试过:

type InferableMappedSelector<S> = <T extends Selector<string, any>[]>(...values: T) => MappedSelector<S, T>

const baz = inferredSelectorCreator(selectors)
// doesn't typecheck due to: 
// Argument of type '[Selector<string, string>, Selector<string, number>]' is not assignable to // parameter of type 'Selector<string, any>'.
//   Type '[Selector<string, string>, Selector<string, number>]' provides no match for the signature // '(a: string): any'.

(最后一点似乎是 TS 中的错误)

最佳答案

你的问题其实很简单。 inferredSelectorCreator接受 T 类型的剩余参数,但是当您打电话时,您会调用 inferredSelectorCreator与整个数组,而不传播它( inferredSelectorCreator(selectors) )这意味着 T将被推断为 [[Selector<string, string>, Selector<string, number>]]而不是[Selector<string, string>, Selector<string, number>] .

如果您使用传播,您会得到预期的结果:

const bazz = inferredSelectorCreator(...selectors)

关于javascript - Typescript 中带有函数的映射类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54366720/

相关文章:

javascript - Active ServiceWorker 并不总是拦截请求

javascript - 在标签浏览器上为新标签设置焦点

javascript - Typescript 中的导出功能

typescript - 动态导入的返回类型是什么?

javascript - 流提示 reducer 中的 Action 联合类型

javascript - TypeScript - 模块在运行时未定义

javascript - 使用 jQuery 选择中的自动单击选项

html - ngtsc(2345) - 'Event' 类型的参数不能分配给 'SortEvent' 类型的参数

javascript - 如何在 Chai 的单元测试中使用 localStorage

javascript - 类型错误 : Cannot read property 'events' of undefined