【问题标题】:Typing Array of T to Array of ReturnType of T将 T 的数组键入 T 的 ReturnType 数组
【发布时间】:2020-01-28 21:06:25
【问题描述】:

我正在尝试将参数的结果映射到回调,并且我正在努力在 TypeScript 中键入它。 我有以下功能:

type CustomRouteType<TParam = any> = <T>(value?: T) => TParam;
const createRoute = <TTypes extends CustomRouteType[]>
    (dictionary: RouteDictionary<TTypes>,
    callback: (...params: TTypes) => void) => {

    // Logic Here
}
createRoute(
    route`/api/someEndpoint/${Number}/${String}/test`, 
    (p1, p2) => {

});

路由函数将字符串文字转换为自定义字典,该字典公开路由中的参数,因此我无法预先知道路由函数可能返回的类型。 在示例中,这将返回一个 RouteDictionary 并且我在回调中设置 p1 和 p2 的方式是那些构造函数,我想将这些参数映射为这些构造函数的 ReturnValue 的类型.

Typescript 只有 ReturnValue 而不是 ReturnValues 我如何映射这些类型以便回调函数的参数推断出我正在寻找的返回类型?

供参考:

class RouteString { 
    constructor(public routeString: string) { } 
}
class RouteParameter<T = any> { 
    constructor(public routeString: CustomRouteType<T>) { } 
}

type RouteDictionary<TTypes extends CustomRouteType[]> = {
    routeParts: (RouteString | RouteParameter)[]
    types: TTypes
}

const route = <TParams extends any[], TTypes extends CustomRouteType<any>[]>
    (template: TemplateStringsArray, ...keys: TTypes): RouteDictionary<TTypes> => {

    let routeParts: (RouteString | RouteParameter)[] = [];
    const stringParts = template.raw || [];

    for (let partIndex = 0; partIndex < stringParts.length; partIndex++) {
        const part = stringParts[partIndex];
        const stringChunks = part.split('/').filter(chunkPart => chunkPart !== String())

        routeParts = [... routeParts, ...stringChunks.map(chunk => new RouteString(chunk))]

        if (keys.length === 0) continue
        if (keys.length < partIndex) continue

        const routeParam = keys[partIndex]
        if (!routeParam) continue

        routeParts = [...routeParts, new RouteParameter(routeParam)]
    }

    return {
        routeParts,
        types: keys
    };
}

【问题讨论】:

  • 您能否包括RouteDictionaryroute 的定义或它们的来源?
  • 我认为这对问题没有影响,我会添加它

标签: typescript typescript-typings


【解决方案1】:

您可以使用映射类型将函数元组映射到返回值元组:

type ReturnValuesOf<T extends Array<(...a: any[]) => any>> = {
  [P in keyof T]: T[P] extends (...a: any[]) => any ? ReturnType<T[P]> : never
}
type RouteDictionary<T> = T 
type CustomRouteType<TParam = any> = <T>(value?: T) => TParam;
const createRoute = <TTypes extends CustomRouteType[]>
    (dictionary: RouteDictionary<TTypes>,
    callback: (...params: ReturnValuesOf<TTypes>) => void) => {

    // Logic Here
}

function route<T extends any[]>(s: TemplateStringsArray, ...arr: T) :T {
  return arr;
}
createRoute(    
    route`/api/someEndpoint/${Number}/${String}/test`, 
    (p1, p2) => { // p1 number, p2: string 

});

【讨论】:

  • 我还是不太明白这是如何正确映射类型的。但它确实正确映射了类型!
  • @MarvinBrouwer 它只是一个映射类型.. typescriptlang.org/docs/handbook/… 该手册描述了它也适用于元组的对象
  • 我明白了,我很难理解传播运算符的含义。但是我现在看到了,您将数组的类型映射到基本上具有任意数量参数的任何类型的函数
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-05-30
  • 1970-01-01
  • 2019-03-22
  • 1970-01-01
  • 2011-07-27
  • 1970-01-01
相关资源
最近更新 更多