gpt4 book ai didi

typescript - 在 TypeScript 中制作所需的函数参数

转载 作者:行者123 更新时间:2023-12-03 20:49:07 26 4
gpt4 key购买 nike

在以下代码中:

type NoArg = {
(): void
}

type OneArg = {
(x:number): void
}

let noArg: NoArg = (x:number)=>{}
let oneArg: OneArg = ()=>{}
只有第一个分配会产生编译器错误。我理解为什么会这样,因为 JavaScript 允许传递的函数少于其完整的可能参数集,这与说参数是可选的不同,这与函数的调用方式而不是传递方式有关。见 the FAQ .
但话虽如此,有没有办法构造一个不兼容零参数函数的 OneArg 接口(interface)版本?
我知道这可以通过品牌或名义打字来完成,例如,
type OneArg = {
(x:number): void
_brand: “OneArg”
}
但是,或者任何其他类型的标称类型解决方案,都需要在分配上做额外的工作(例如,您必须显式地将 _brand 属性添加到函数中)。
所以我的问题是——有没有什么方法可以构造一个类型 NoArg 会使简单赋值失败 let oneArg: OneArg = ()=>{} ?
上面链接的常见问题解答说“TypeScript 目前没有办法指示必须存在回调参数。”这是否完全排除了我想在这里做的事情?我希望它不会,因为这不是回调参数,但也许原理是一样的。
更新:在下面的评论中,提出了一个问题,即这是否可以通过类型保护测试来实现。据我所知,答案是否定的,因为类型重叠意味着类型保护不会缩小类型。您可以在 this playground 中看到它.

最佳答案

在与@aluan-haddad 讨论后,我有一个部分解决方案。我无法得到我所要求的确切内容,即一个“自动”类型定义,可以区分具有所需参数的函数和没有参数的函数,但我想出了一个“鉴别器”函数,可以区分这两个函数并应用适当的品牌类型。
该解决方案依赖于使用条件类型,再加上单参数函数与零参数类型不兼容的事实(即使反过来不正确)来强制正确的类型。

type NoArg = {
_brand: 'NoArg'
():void
}

type OneArg = {
_brand: 'OneArg'
(x:number): void
}

// Correct typings
let noArg: NoArg = discriminator(()=>{})
let oneArg: OneArg = discriminator((x:number)=>{})

// Both of these error, as hoped!
let noArgError: NoArg = discriminator((x:number)=>{})
let oneArgError: OneArg = discriminator(()=>{})

function discriminator<T extends (x:any)=>any>(myFunc: T) {
let discriminatedFunc
if(myFunc.length === 0) {
discriminatedFunc = {
_brand: 'NoArg',
myFunc
}
}
else {
discriminatedFunc = {
_brand: 'OneArg',
myFunc
}
}
return discriminatedFunc as unknown as T extends ()=>any ? NoArg : OneArg
}
以及 a playground .
注意:就我的观点而言,这依赖于一个参数函数与零类型函数不兼容,请注意条件类型的反向版本 T extends (x:number)=>any ? OneArg : NoArg将不起作用,因为它总是解析为 OneArg。
现在,这是否比首先通过构造函数“标记”函数更好?我认为是这样,因为您只需要一个鉴别器功能而不是两个品牌功能。而且还因为您不一定需要事先知道函数的签名,即,当您将它们传递给鉴别器时。
有人看到这个解决方案有什么问题吗?有没有更好的,或者这都是 TS 允许的?

关于typescript - 在 TypeScript 中制作所需的函数参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63800920/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com