【发布时间】:2022-01-12 19:52:17
【问题描述】:
我已经编写了一个小库,现在我正在尝试通过创建自定义 d.ts 文件来为其添加类型支持。
举个例子(我的库叫做layerCompose):
const C = layerCompose(
{
_($) { /* function body */ },
execute($) { /* function body */ }
}
)
const c = C()
c._()
您会注意到_ 和execute 函数都带有一个参数$。
此参数(在我们的示例中)是具有_ 和execute 属性的对象(类似于类中的this)
所以,我想为这个$ 参数添加类型支持。通过实验,我发现在我的 d.ts 文件中包含此定义可以在 _ 函数中提供类型支持。
export function layerCompose<
T extends [
A extends {}
? {
_($: {test: () => void})
}
: never
]
, A
>(...layers: T): lcConstructor<Spread<T>>
也就是说Webstorm可以看到_函数中的$参数的类型是{test: () => void}
显然,这不是我想要的。但是,将签名更改为(我认为合适的)
export function layerCompose<
T extends [
A extends {}
? {
[K in keyof A]: ($: {test: () => void}) => any
}
: never
]
, A
>(...layers: T): lcConstructor<Spread<T>>
Webstorm 失去了判断$ 是具有_ 和execute 属性的对象的能力。
编辑:Included an example on typescript playground。它缺少返回类型(快速设置它并非易事),但可以深入了解layerCompose 的大致作用。
编辑 2:
进一步玩,已简化为 1 个参数场景,这是可行的:
export function layerCompose<L1>(l1: {_: ($: {test: () => void}) => void} & L1): void
但事实并非如此:
export function layerCompose<L1>(l1: {[K in keyof L1]: ($: {test: () => void}) => void} & L1): void
【问题讨论】:
-
A是如何被解析的,为什么在函数签名中没有用到它?您应该为您的问题编写一个完全可重现的示例。 typescriptlang.org/play 将受到欢迎 -
您提供的用于键入
layerCompose的示例始终会生成T = never。你确定他们被使用了吗? Webstorm 可能无法正确识别您的声明文件。 -
@GuerricP 示例已添加。
-
@Olian04 我一直在努力确保传播对我的 d.ts 文件的更新。我可以看到 Webstorm 何时获取签名以及何时失败。
标签: typescript types type-hinting