我正在尝试将参数的结果映射到回调,而我正在努力在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) => {
});
route函数将字符串文字转换为自定义字典,该字典公开了路由中的参数,因此我无法预先知道route函数可能返回的类型。 在示例中,这将返回RouteDictionary <[NumberConstructor,StringConstructor]>,而我在回调中设置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
};
}
答案 0 :(得分:2)
您可以使用映射类型将函数的元组映射到返回值的元组:
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
});