我希望创建一个T
在最后一个参数位置使用type表示这些函数的类型。可变参数元组类型看起来可以毫无问题地解决此问题,但是在我目前的方法中,类型如下:
type TasLastArg<T> = (...args: [...any, T]) => any;
args
争论已经变成了any[]
。其他地方也有类似的行为,使我认为这应该是可能的。当前行不通的示例/我认为有可能的原因:
type TasFirstArg<T> = (...args: [T, ...any]) => any; // this appears to work as expected
type TasLastArg<T> = (...args: [...any, T]) => any; // would like for this to work
namespace T_in_first_place {
const ok : TasFirstArg<string> = (x:string, y: number, z: string) => { return 0; }
const correctly_fails : TasFirstArg<string> = (x:number, y: number, z: number) => { return 0; }
}
namespace T_in_last_place {
const ok : TasLastArg<string> = (x:number, y: number, z: string) => { return 0; }
const should_fail_but_does_not: TasLastArg<string> = (x:number, y: number, z: number) => { return 0; }
}
// there is some machinery that allows looking at the last type in a tuple:
type CheckStringIsLast<T extends any[]> = T extends [...infer first, string] ? true : false;
type it_checks_this_fine = CheckStringIsLast<[number, number, string]>; // true
type it_properly_rejects_this = CheckStringIsLast<[number, number, number]>; // false
是不可能的,还是我错过了什么?
TypeScript 4.1仅在元组类型的末尾支持rest元素。可变的元组类型允许您编写 [...any, T]
,但是折叠到any[]
。
当发布TypeScript 4.2时,它应该开始在其开头或中间开始接受rest元素(但每个元组仅接受一个rest元素)。有关实现此功能的PR,请参阅microsoft / TypeScript#41544。此时,将按您的意图[...any, T]
解释为[...any[], T]
,表示“T
末尾有任何元组”。
请注意,但是一旦支持,您的示例就不会真正实现您的预期:
const ok : TasLastArg<string> = (x:number, y: number, z: string) => { return 0; } // error!
// -> ~~
// Target requires 3 element(s) but source may have fewer
这是一个错误,因为当目标函数确实需要一个string
作为最后一个元素,它不符合TasLastArg<string>
,这就需要将接受一个函数的任何参数列表,在一个结束string
。这意味着您需要能够通过以下方式进行调用:
ok("shouldWork");
ok(1, 2, 3, 4, 5, 6, 7, true, new Date(), "shouldAlsoWork");
(x: number, y: number, z: string) => number
如果type的实现对,和进行了任何有意义的操作x
,则对于type函数将是灾难性的。如果要实现它需要以正确的方式本身就是可变的函数:y
z
const reallyOkay: TasLastArg<string> = (...args: [...initArgs: any[], lastArg: string]) => {
console.log((args[args.length - 1] as string).toUpperCase());
}
reallyOkay("shouldWork"); // SHOULDWORK
reallyOkay(1, 2, 3, 4, 5, 6, 7, true, new Date(), "shouldAlsoWork"); // SHOULDALSOWORK
而且,至少在最初,它似乎还不会自动args[args.length-1]
解释string
。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句