我正在使用 JSDoc,并对
Stream<T>
有以下定义:
/**
* @template T
* @callback Stream
*
* @param {T} [value]
*
* @return {T} the value
*/
这正确地翻译为
index.d.ts
中的以下定义:
export type Stream<T> = (value?: T) => T;
但是,
Stream
是一个也具有 map
属性的函数。 map
是一个创建另一个流的函数:
const s = stream(); // s is a Stream
s(5); // s is a function
// but s.map is also a function
const s2 = s.map(x => x + 1);
如何使用 JSDoc 定义
Stream<T>
?以下不起作用:
/**
* @template T
* @callback Stream
*
* @param {T} [value]
* @property {Function} map
*
* @return {T} the value
*/
这不会生成
map
,更糟糕的是,失去了函数返回 T
的事实:
export type Stream<T> = (value?: T) => any;
理想情况下,我希望生成这个(或等效的):
export interface Stream<T> {
(value?: T) => T;
map<U>(fn: (value: T) => U): Stream<U>;
}
有没有办法用 JSDoc 来实现这一点?
对于 VSCode 的智能感知,我已经开始实现类似的东西,使用 JSDoc 定义回调类型。它可能也适用于这种情况。
我还没有遇到过在 JSDoc 注释中定义接口类型,但可以在实际实现中定义。首先定义函数流
/**
* @template T
* @function Stream
*
* @param {T} [value]
*
* @return {T} the value
*/
function Stream(value) {
//@ts-ignore
return value;
}
我将
@callback
标签更改为 @function
,因为否则 Stream
类型与定义的 Stream.map
属性一起不正确:
Stream(); // (local function) Stream(value: any): any
接下来定义属性映射。
/**
* @template T inputted value
* @template U mapped value
*
* @param {(value: T) => U} fn
*/
Stream.map = function (fn) {
return fn;
};
因此
s
是“接口”函数,其中 map
属性作为方法。
// intellisense shows type similar to asked Stream interface:
// const s: {
// <T>(value?: T | undefined): T;
// map<T, U>(fn: (value: T) => U): (value: T) => U;
const s = Stream;
// }
// const s: <5>(value?: 5 | undefined) => 5
s(5);
const s2 = s.map(
/** @param {Number} x */
x => x + 1
);
// const s2: (value: number) => number
s2(8);