繁体   English   中英

打字稿用void return tupe定义任意函数

[英]Typescript define arbitrary function with void return tupe

我想写一些装饰器函数,以函数为参数:

type SomeType = ??? => void;

const decorate = (fn: SomeType): SomeType => {
   ...
} 

我如何定义“SomeType”,以限制仅对具有 void 返回类型的函数进行装饰调用?

const f1 = decorate((a: number) => {console.log(a);});   //OK
const f2 = decorate((a: number, b: string) => {console.log(a,b);}); //OK
const f3 = decorate((a: number, b: number) => {console.log(a,b); return a+b;});  //Not allowed

这应该对你有用。

type SomeType = (...args: any) => void;

我将链接它,因为它与您的情况相关,如果您输入一个没有 void 返回类型的函数,它不会抛出错误https://github.com/microsoft/TypeScript/wiki/FAQ#why -are-functions-returning-non-void-assignable-to-function-returning-void

问题有两个部分。 通过decorate函数保留参数类型。 并确保装饰函数的返回类型为void

您可以通过向decorate添加通用参数来解决第一部分。 这将调用decorate捕获实际参数:

const decorate = <A extends any[]>(fn: (...a: A) => void): (...a: A) => void => {
   return fn;
} 

const f1 = decorate((a: number) => {console.log(a);});   //(a: number) => void;
const f2 = decorate((a: number, b: string) => {console.log(a,b);}); //(a: number, b: string) => void;
const f4 = decorate((a: number, b: number) => {console.log(a,b); return a+b;}); //(a: number, b: number) => void;

游乐场链接

第二部分有点棘手,签名中的void并不一定意味着函数不会返回值,而是调用者不会观察到任何返回值。 虽然在声明具有显式返回void的函数时有一些保护措施(例如: function x(): void { return 1 } ),但通常返回任何内容的函数可以分配给需要void的签名

function x() { return 1 }
let y : () => void = x

游乐场链接

话虽如此,因为您确实需要在另一个函数( decorate函数)中使用它,我们可以捕获您传入的任何函数的实际返回类型,并使用条件类型强制一种自定义错误:

const decorate = <A extends any[], R>(fn: ((...a: A) => R & (void extends R ? unknown : ["Void required allowed"]))): (...a: A) => void => {
   return fn;
} 

const f1 = decorate((a: number) => {console.log(a);});   //OK
const f2 = decorate((a: number, b: string) => {console.log(a,b);}); //OK
const f3 = decorate((a: number, b: number) => {console.log(a,b); return a+b;}); //    Type 'number' is not assignable to type '["Void required allowed"]'.

游乐场链接

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM