简体   繁体   English

IntelliSense/JSDoc @param = @return,也就是我如何记录包装函数?

[英]IntelliSense/JSDoc @param = @return, a.k.a. how do I document wrapper functions?

I have a function which takes in another function as an argument, does something to that function-argument, and then returns that same function-argument (or at least returns a function with the exact same signature to it)我有一个 function 接受另一个 function 作为参数,对该函数参数执行某些操作,然后返回相同的函数参数(或至少返回一个 ZC1C425268E68385D1ABZ5074C 与完全相同的签名)

/**
 * The param and return should be the same (as far as JSDoc is concerned)!
 * @param {Function} fnToWrap
 * @returns {fnToWrap}
 */
function wrapperFunction(fnToWrap) {
    // Does something...
    return fnToWrap;
}

However, as you can see from my comments in the following...但是,正如您从我在下面的评论中看到的那样......

/**
 * IntelliSense detects this...
 * @param paramA 
 * @returns 
 */
var arbitraryFn = function(paramA) {
    return paramA * 2;
}


// But NOT this!!!
var wrappedArbitraryFn = wrapperFunction(arbitraryFn);

... IntelliSense will autocomplete when calling arbitraryFn() but not wrappedArbitraryFn() . ... IntelliSense 将在调用arbitraryFn() Fn() 时自动完成而不是wrappedArbitraryFn()

Is there any way to get IntelliSense to dynamically autocomplete my wrapped functions with the same signature as their unwrapped counterparts, ie without having to explicitly re-document every newly-wrapped function?有没有办法让 IntelliSense动态地自动完成我的包装函数,其签名与未包装的函数相同,即无需显式重新记录每个新包装的 function?

I'm revisiting this again as I now have a (near-)perfect solution for my use-case.我正在重新审视这一点,因为我现在为我的用例提供了一个(近乎)完美的解决方案。 The reality is IntelliSense is far more TypeScript than it is standard JSDoc.现实情况是,IntelliSense标准 JSDoc 更多的是 TypeScript。 As it turns out, you can leverage the @template tag to solve the above, and as far as I've seen, anything I can accomplish in TypeScript I can also accomplish in JavaScript IntelliSense :事实证明,您可以利用@template标签来解决上述问题,据我所知,我可以在 TypeScript 中完成的任何事情我也可以在 JavaScript IntelliSense 中完成

The New Wrapper Function新包装 Function

/**
 * The param and return should be the same (as far as JSDoc is concerned)!
 * @template {Function} T
 * @param {T} fnToWrap
 * @returns {T}
 */
 function wrapperFunction(fnToWrap) {
    // Does something...
    return fnToWrap;
}

Wrapping a Previously-Declared Function包装先前声明的 Function

/**
 * IntelliSense detects this...
 * @param {Number} paramA 
 */
function previouslyDeclared(paramA) {
    return paramA * 2;
}

// And it also detects this!
var afterWrapping = wrapperFunction(previouslyDeclared);

Wrapping an inline Function包装内联 Function

// And it also detects this!
var wrappedArbitraryFn = wrapperFunction(
    /**
     * IntelliSense detects this
     * @param {String} a 
     * @param {Number} b 
     * @param {Function} c 
     * @returns 
     */
    (a, b, c) => {
        return 22;
    }
);

Only downside for me is the inline is a bit ugly, imo, but it works.对我来说唯一的缺点是内联有点难看,imo,但它有效。 However, do note that this may not be a valid solution for true/vanilla JSDoc .但是,请注意,这可能不是 true/vanilla JSDoc 的有效解决方案 This solution is great if, like me, you don't really use/care about JSDoc and you're really just here for the IntelliSense piece.如果像我一样,如果您并不真正使用/关心 JSDoc,并且您真的只是为了 IntelliSense 作品,那么这个解决方案非常棒。

This isn't exactly what I'm looking for, but after posting this question I did discover this method which isn't too bad:不是我正在寻找的东西,但是在发布这个问题之后,我确实发现了这种方法还不错:

/**
 * @type {arbitraryFn}
 */
var wrappedArbitraryFn = wrapperFunction(arbitraryFn);

This works and isn't too tedious, however be aware of the following:这很有效,而且不会太乏味,但是请注意以下几点:

  • This requires pre-defining the original function.这需要预先定义原始的 function。 In other words, I can't get this to work for functions declared inside the call to the wrapper function, eg this won't work for var wrapped = wrapperFunction((a, b) => a + b)换句话说,我不能让它适用于在调用包装器 function 中声明的函数,例如这不适用于var wrapped = wrapperFunction((a, b) => a + b)
  • This will break if you try to rename the function with the "Rename Symbol" command (F2) in Visual Studio Code unless you document the original function with an @typedef .如果您尝试在 Visual Studio Code 中使用“重命名符号”命令 (F2) 重命名 function,这将中断除非您使用 @typedef 记录原始@typedef Putting a @typedef every time might be fine, but I don't know if there are any side effects to that tag.每次都放一个@typedef可能没问题,但我不知道该标签是否有任何副作用。 Plus it's an extra step to remember, and one that doesn't have obvious/immediate consequences if you forget it另外,这是要记住的一个额外步骤,如果您忘记它,它不会产生明显/直接的后果

So I'm still very open to answers!所以我仍然非常愿意接受答案!

@user3781737 solution worked for me, after 6+ hours of debugging.经过 6 个多小时的调试,@user3781737 解决方案对我有用。

If anyone is having trouble getting props suggestions to work on components with forwarded props ie: {...props} I have found this solution using JSdoc @type annotation.如果有人在获取道具建议以处理具有转发道具的组件时遇到问题,即:{...props} 我使用 JSdoc @type 注释找到了这个解决方案。 It requires you have access to the props of the component where you are forwarding the props to:它要求您可以访问要将道具转发到的组件的道具:

import React from 'react';
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
import { HeaderButton, HeaderButtonProps } from 'react-navigation-header-buttons';
import PropTypes from 'prop-types';

/**
 * Used to wrap react-navigations default headerButton. 
 *
 * @type {React.FC<ButtonPropTypes & HeaderButtonProps>}
 */
const DefaultHeaderButton = props => {
    return (
        <HeaderButton 
            {...props} 
            IconComponent={MaterialCommunityIcons} 
            iconSize={30} 
            color={props.color || "#fff"}
        />
    );
};

DefaultHeaderButton.displayName = 'DefaultHeaderButton';
const ButtonPropTypes = {
    color: PropTypes.string
}
DefaultHeaderButton.propTypes = ButtonPropTypes;

export default DefaultHeaderButton;

Edit: I realized this is only necessary if the propTypes are a typescript interface while using javascript.编辑:我意识到只有在使用 javascript 时 propTypes 是 typescript 接口时才需要这样做。 In most cases you can just spread the original item's propTypes into your custom propTypes.在大多数情况下,您可以将原始项目的 propTypes 传播到您的自定义 propTypes 中。

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

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