Typescript:函数参数的类型辅助

Ant*_*ton 9 types type-hinting typescript

我编写了一个小库,现在我尝试通过创建自定义 d.ts 文件为其添加类型支持。

举个例子(我的图书馆叫layerCompose):

const C = layerCompose(
  {
     _($) { /* function body */ },
     execute($) { /* function body */ }
  }
)
const c = C()
c._()
Run Code Online (Sandbox Code Playgroud)

您会注意到 和_functionexecute都带有一个参数$。此参数(在我们的示例中)是一个具有_execute属性的对象(类似于this在类中)

因此,我想为此$参数添加类型支持。通过实验,我发现在 d.ts 文件中包含此定义可以在函数内提供类型支持_

export function layerCompose<
  T extends [
    A extends {} 
      ? {
        _($: {test: () => void})
      } 
      : never
  ]
  , A
>(...layers: T): lcConstructor<Spread<T>>
Run Code Online (Sandbox Code Playgroud)

换句话说Webstorm可以看到函数$中的参数_有类型{test: () => void}

显然,这不是我想要的。但是,将签名更改为(对我来说合适的)

export function layerCompose<
  T extends [
    A extends {} 
      ? { 
        [K in keyof A]: ($: {test: () => void}) => any 
      } 
      : never
  ]
  , A
>(...layers: T): lcConstructor<Spread<T>>
Run Code Online (Sandbox Code Playgroud)

Webstorm 失去了判断该$对象具有属性_和 的能力execute


编辑:包括打字稿游乐场上的示例。它缺少返回类型(快速设置它并不简单),但在其他方面可以深入了解layerCompose大约的作用。


编辑2:

进一步尝试,简化为 1 个参数场景,这是有效的:

export function layerCompose<L1>(l1: {_: ($: {test: () => void}) => void} & L1): void
Run Code Online (Sandbox Code Playgroud)

但这并没有:

export function layerCompose<L1>(l1: {[K in keyof L1]: ($: {test: () => void}) => void} & L1): void
Run Code Online (Sandbox Code Playgroud)

Oli*_*n04 2

这是您要找的吗?

export function layerCompose(...layers: Layer[]): lcConstructor<Spread<T>>;
Run Code Online (Sandbox Code Playgroud)

由于您都没有定义,lcConstructor或者我无法对Spread的返回类型应该是什么做出任何真正的猜测。layerCompose因此,出于本答案的目的,这些类型已替换为身份类型。

// See playground below
type ComposedLayer = {
  _(): void;
  execute(): void;
}
type Layer = {
  _(v: Layer): void;
  execute(v: Layer): void;
}

/* dummy type */ type lcConstructor<T> = ComposedLayer;
/* dummy type */ type Spread<T> = T;

declare function layerCompose(...layers: Layer[]): lcConstructor<Spread<Layer>>;

const C = layerCompose(
  {
     _($) {},
     execute($) {
       $._({
         _($) {},
         execute($) {}
       })
     }
  }
);

C._();
Run Code Online (Sandbox Code Playgroud)

操场