繁体   English   中英

具有功能的Typescript中的映射类型

[英]Mapped Types in Typescript with functions

我在使用映射类型时遇到了一些麻烦。

我正在尝试键入一个组成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类型的rest参数,但是当您调用时,将整个数组都调用inferredSelectorCreator而不扩展它( inferredSelectorCreator(selectors) ),这意味着T将被推断为[[Selector<string, string>, Selector<string, number>]]代替[Selector<string, string>, Selector<string, number>]

如果使用点差,您将得到预期的结果:

const bazz = inferredSelectorCreator(...selectors)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM