在Typescript中创建函数类型模板

在Typescript中创建函数类型模板,typescript,typeof,Typescript,Typeof,我有一个类似以下的函数,只是简单得多: function foo(arg1?: string | number | boolean, arg2?: number | boolean, arg3?: boolean) { // omitted } 此功能可以以多种不同的方式运行,例如: foo(); foo(1, true); foo("", false); foo(4); foo(true); // ..etc 为了使上下文线索/类型定义可读,最好的方法是使用重载: function f

我有一个类似以下的函数,只是简单得多:

function foo(arg1?: string | number | boolean, arg2?: number | boolean, arg3?: boolean) {
  // omitted
}
此功能可以以多种不同的方式运行,例如:

foo();
foo(1, true);
foo("", false);
foo(4);
foo(true);
// ..etc
为了使上下文线索/类型定义可读,最好的方法是使用重载:

function foo();
function foo(name: string);
function foo(age: number);
function foo(nice: boolean);
function foo(name: string, age: number);
function foo(name: string, nice: boolean);
function foo(age: number, nice: boolean);
function foo(name: string; age: number, nice: boolean);
function foo(arg1?: string | number | boolean, arg2?: number | boolean, arg3?: boolean) {
  // omitted
}

// now it'll figure out which overload I'm on, and give easier to read insights
问题是我不只是有foo。我有foo、bar、qux、baz和其他30种音乐。写这一切将是一堵可怕的文字墙。所以我试着为所有人制作一种类型,如果不是泛型的话,它会起作用:

// Without generics, this problem would be solved

export const bar = (function(...args: ArgOutline) {
  // omitted
}) as typeof foo

export const qux = (function(...args: ArgOutline) {
  // omitted
}) as typeof foo

export const baz = (function(...args: ArgOutline) {
  // omitted
}) as typeof foo

/// and so on...

我真正想要的是一个大纲函数,它接受泛型并可以生成具有可读性见解的内容,但以下代码不起作用:

function Outline();
function Outline(name: string);
function Outline<PROPS>(props: PROPS);
function Outline(name: string props: PROPS);
function Outline<PROPS>(arg1?: string | PROPS, arg2?: PROPS) {
  // omitted
}


// This doesn't work
export const baz = (function(...args: ArgOutline) {
  // omitted
}) as typeof Outline<{a: number}> 
函数大纲();
功能大纲(名称:字符串);
功能大纲(道具:道具);
功能大纲(名称:字符串道具:道具);
函数大纲(arg1?:字符串|道具,arg2?:道具){
//省略
}
//这不管用
export const baz=(函数(…args:ArgOutline){
//省略
})作为轮廓的类型
我已经读到了为什么你不能这么做(),但似乎还是有办法的,只是不是这样


我怎样才能创建一个泛型类型,它将产生一些洞察,比如说
(+N重载)
,而不是
()=>reallytriblylongname |(name:string)=>reallytriblylongname |(name:string,props:AlsoATerriblyLongName)=>reallytriblylongname |等等

从床上爬起来就是为了这个

function Outline<PROPS>() {

  function out();
  function out(name: string);
  function out(props: PROPS);
  function out(name: string props: PROPS);
  function out(arg1?: string | PROPS, arg2?: PROPS) {
    // omitted
  }

  return out;
}

// Create the outline, then get its type
const bazOutline = Outline<{a: number}>();
export const baz = (function(...args: ArgOutline) {
  // omitted
}) as typeof bazOutline

函数大纲(){
函数out();
函数输出(名称:字符串);
功能输出(道具:道具);
函数输出(名称:字符串props:props);
函数输出(arg1?:字符串|道具,arg2?:道具){
//省略
}
返回;
}
//创建轮廓,然后获取其类型
const bazOutline=Outline();
export const baz=(函数(…args:ArgOutline){
//省略
})作为提纲的类型
创建一个返回所需类型函数的函数。然后从中得到类型。。。仍然需要在野外测试,但我现在得到了正确的类型定义。可能导出会中断。

尝试界面(我假设您的返回类型为void):

接口概要{
():无效;
(名称:字符串):无效;
(道具:道具):无效;
(名称:字符串,道具:道具):无效;
}
导出常量条=函数(…args:any[]){}作为大纲;
您还可以将泛型参数移动到接口本身:

interface Outline<PROPS> {
    (): void;
    (name: string): void;
    (props: PROPS): void;
    (name: string, props: PROPS): void;
}

export const bar = function(...args: any[]) { } as Outline<{ a: number }>;
接口概要{
():无效;
(名称:字符串):无效;
(道具:道具):无效;
(名称:字符串,道具:道具):无效;
}
导出常量条=函数(…args:any[]){}作为大纲;

我醒来时想到了这一点。很高兴看到这是最好的方式。
interface Outline<PROPS> {
    (): void;
    (name: string): void;
    (props: PROPS): void;
    (name: string, props: PROPS): void;
}

export const bar = function(...args: any[]) { } as Outline<{ a: number }>;