Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Typescript 如何将带有泛型的函数类型应用于函数_Typescript - Fatal编程技术网

Typescript 如何将带有泛型的函数类型应用于函数

Typescript 如何将带有泛型的函数类型应用于函数,typescript,Typescript,我有以下类型: type AllRoutes = { Home: undefined Page: { id: string } } type NavFunction<RouteName extends keyof AllRoutes> = ( ...args: AllRoutes[RouteName] extends undefined ? [RouteName] : [RouteName, AllRoutes[RouteName]] ) => v

我有以下类型:

type AllRoutes = {
  Home: undefined
  Page: { id: string }
}

type NavFunction<RouteName extends keyof AllRoutes> = (
  ...args: AllRoutes[RouteName] extends undefined
    ? [RouteName]
    : [RouteName, AllRoutes[RouteName]]
) => void
键入所有路由={
主页:未定义
页面:{id:string}
}
类型NavFunction=(
…args:AllRoutes[RouteName]扩展未定义
?[路由名称]
:[RouteName,AllRoutes[RouteName]]
)=>无效
如果我将此类型直接放在这样的函数上,它将按预期工作:

export function navigate<RouteName extends keyof AllRoutes>(
  ...args: AllRoutes[RouteName] extends undefined
    ? [RouteName]
    : [RouteName, AllRoutes[RouteName]]
) {
  ...
}

navigate('Home') // works!
navigate('Page', {id: 1}) // works!
navigate('Page') // Expected 2 args
导出功能导航(
…args:AllRoutes[RouteName]扩展未定义
?[路由名称]
:[RouteName,AllRoutes[RouteName]]
) {
...
}
导航('Home')//工作!
导航('Page',{id:1})//工作!
导航('Page')//应为2个参数

我遇到的问题是,我想将这种类型应用于多个函数(每个函数用于不同的平台)。我似乎不知道如何将第一种类型应用于函数,并使其像我刚刚发布的“direct”示例一样工作。

您可以为
args
部分创建一个帮助器类型。也可以为所有路由的
键创建一个类型
?:

type RouteNames = keyof AllRoutes;
type GetArgs<RouteName extends RouteNames> = AllRoutes[RouteName] extends undefined
    ? [RouteName]
    : [RouteName, AllRoutes[RouteName]];

export function navigate<RouteName extends RouteNames>(
  ...args: GetArgs<RouteName>
) {
  ...
}
type routename=keyof all routes;
类型GetArgs=AllRoutes[RouteName]扩展未定义
? [路由名称]
:[RouteName,AllRoutes[RouteName]];
导出功能导航(
…args:GetArgs
) {
...
}

首先,请注意,
NavFunction
类型虽然类似于
navigate
的函数类型,但实际上并不相同。它应该将泛型部分附加到函数,而不是类型名,如下所示:

// Note the generic part is now attached to the start of the function
// signature, rather than as a part of the NavFunction type name.
type NavFunction = <RouteName extends keyof AllRoutes>(
  ...args: AllRoutes[RouteName] extends undefined
    ? [RouteName]
    : [RouteName, AllRoutes[RouteName]]
) => void
但请注意,以这种方式操作时,
导航
功能将不再被提升:(

这不是一个直接的答案,而是一个改变问题的建议

这类函数的预期用途很好,但需要一个不容易维护的类型。使用一个带有区分联合类型的整个对象参数怎么样

//按名称区分的路由
键入HomeRoute={name:'Home'};
键入PageRoute={name:'Page';id:number};
键入SearchRoute={name:'Search';text:string;limit?:number};
类型路由=HomeRoute | PageRoute | SearchRoute;
函数navigateV1(route:route):void{/*…*/}
navigateV1({name:'Home'})
navigateV1({name:'Page',id:1})
navigateV1({name:'Page'})//出现预期错误“缺少属性“id…”
navigateV1({name:'Search',text:'A*'})
用法只是有点冗长,但也给出了更详细的错误

--

顺便说一句,对于上述有区别的联合类型,为了坚持所需的用法,我们还需要复杂的实用程序类型:

//V2(维护起来更复杂):作为解构对象的参数
键入RouteName=Route['name'];/“Home”|“Page”|“Search”
类型路由=
{}扩展树
?[TRouteName]
:[TRouteName,TRest];
键入TestHomeRouteArgs=RouteArgs;//[“Home”]
键入TestPageRouteArgs=RouteArgs;//[“页面”,选择]
键入TestSearchRouteArgs=RouteArgs;//[“搜索”,选择]
函数navigateV2(…参数:RouteArgs):void{/*…*/}
导航EV2(“主页”)
navigateV2('Page',{id:1})
navigateV2('Page')//得到了预期的错误,但不太准确:“预期有2个参数,但得到了1个”
navigateV2('Search',{text:'A*'})
// ----
//V3:更复杂但输出类型更可读
类型Prettify=T扩展推断Tbis?{[K in keyof Tbis]:Tbis[K]}:从不;
类型预齿=
{}扩展树
?[TRouteName]
:[TRouteName,美化];
类型TestPrettyHomeRouteArgs=PrettyRouteArgs;//[“Home”]
键入TestPrettyPageRouteArgs=PrettyRouteArgs;//[“Page”,{id:number;}]
键入TestPrettySearchRouteArgs=PrettyRouteArgs;//[“搜索”{text:string;limit?:number | undefined;}]
函数navigateV3(…args:PrettyRouteArgs):void{/*…*/}
导航EV3(“主页”)
navigateV3('Page',{id:1})
navigateV3('Page')//得到了相同的预期错误
navigateV3('Search',{text:'A*'})

太好了!我需要进行以下编辑,但它似乎可以工作:
GetArgs
->
GetArgs
const navigate: NavFunction = function(...args) {
  // ...
}

navigate('Home') // works!
navigate('Page', {id: "1"}) // works!
navigate('Page') // Expected 2 args